create project

This commit is contained in:
Lyons 2024-06-11 22:05:07 +08:00
commit 56410482db
244 changed files with 69471 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!LICENSE
!*.md
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

291
README.md Normal file
View File

@ -0,0 +1,291 @@
22:05 2024/6/11
## 一、简介
> TraSH一个基于 RISC-V 指令集的计算机系统
## 二、功能介绍
### 1. 特性
**TraSH 具有如下特性:**
- 完全采用 Verilog 进行编写
- 具有 5 级流水线,顺序执行,不支持分支预测(取指 IF、译指 ID、执行 EX、访存 MEM、写回 WB
- 支持 RV32IMZicsr 指令集ecall、ebreak、fence、fence.i、wfi 指令除外)
- 仅支持 M 模式
- 仅支持非向量中断
- 非 AMBA 总线,哈佛结构,支持 bootloader
- 支持 UART、TIMER、GPIO 等外设
- 支持 RT-Thread Nano 3.1.5
- 支持在多平台运行
**TraSH 可以在 Windows 和 Linux 平台运行:**
1. Windows 平台 (Win10)
- 支持 iverilog 仿真
- 支持 Gowin FPGA (TANG Nano 9K)
- 支持 XEMU 模拟器
2. Linux 平台 (CentOS)
- 支持 VCS 仿真
- 支持 XEMU 模拟器
### 2. 地址分配
编译的 .bin 可以在多个平台运行,但是由于平台的限制,需要对 rom 和 ram 的大小进行设置
原则上,除了 XEMU 外,其他平台请遵循 `rom=28K, ram=12K`
- vcs、iverilog、Gowin FPGA 均使用了相同的 IP如需修改需要重新生成 IP 进行替换
|起始地址 |结束地址 |大小 |外设 |支持|
|:-: |:-: |:-: |:-: |:-: |
|0x0000_0000|0x0fff_ffff|512K(Max 28K on non XEMU platform)|ROM |√ |
|0x1000_0000|0x1fff_ffff|512K(Max 28K on non XEMU platform)|RAM |√ |
|0x2000_0000|0x2fff_ffff|4K |TIMER1|√ |
|0x3000_0000|0x3fff_ffff|4K |UART1 |√ |
|0x4000_0000|0x4fff_ffff|4K |GPIO |√ |
*实际使用的空间大小详见 link.lds 文件*
## 三、环境搭建
### 1. Windows + iverilog
#### 1. 说明
- 内核及外设:`YuHeng 5-state RISC-V Core`
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210306)`
- 仿真环境:`iverilog + gtkwave`
*注意,当宏 `PRINT_STDIO_SIM` 被定义时,使用 `mscratchcswl` 寄存器来重定向 xprintf需要编译器支持*
#### 2. 操作
修改仿真环境 iverilog 和 gtkwave 的路径(文件路径:`sim/config.mk`
```
VCS = D:/iverilog/bin/iverilog.exe
SIM = D:/iverilog/bin/vvp.exe
WAV = D:/iverilog/gtkwave/bin/gtkwave.exe
```
修改测试程序编译工具的路径(文件路径:`sim/config.mk`
```
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc.exe
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
```
### 2. Windows + XEMU
#### 1. 说明
- 内核及外设:`YuHeng 5-state RISC-V Core`
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210306)`
- 仿真环境:`XEMU`
*注意,不能定义 `PRINT_STDIO_SIM`,即只支持使用 UART 来重定向 xprintf *
#### 2. 操作
下载并安装 `MinGW`,打开网页 `https://sourceforge.net/projects/mingw/files/`,下载 `mingw-get-setup.exe`
安装 gcc、g++、gdb 和 pthread
```
mingw-get install gcc
mingw-get install g++
mingw-get install gdb
mingw-get install pthreads
```
修改 Windows gcc 编译工具的路径(文件路径:`sim/xemu/Makefile`
```
TARGET = .\xemu.exe
CC = D:\MinGW\bin\gcc.exe
PARAM =
LIB = -lpthread -lm
```
修改测试程序编译工具的路径(文件路径:`sim/config.mk`
```
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc.exe
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
```
### 3. Windows + Gowin FPGA
#### 1. 说明
- 内核及外设:`YuHeng 5-state RISC-V Core`
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210306)`
- 仿真环境:`GOWIN FPGA Designer Version 1.9.8.11 Education`
*注意,不能定义 `PRINT_STDIO_SIM`,即只支持使用 UART 来重定向 xprintf *
#### 2. 操作
安装 Gowin IDE
修改测试程序编译工具的路径(文件路径:`sim/config.mk`
```
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc.exe
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
```
*注意,重新编译测试程序后,需要重新生成 IP*
### 4. Linux + VCS
#### 1. 说明
- 内核及外设:`YuHeng 5-state RISC-V Core`
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210307)`
- 仿真环境:`VCS + DVE/Veridi`
*注意,当宏 `PRINT_STDIO_SIM` 被定义时,使用 `mscratchcswl` 寄存器来重定向 xprintf需要编译器支持*
#### 2. 操作
修改测试程序编译工具的路径(文件路径:`sim/config.mk`
```
EMBTOOLPATH = /home/crazy/Tools/compiler/xuantie/v8.4.0/riscv64-elf-x86_64-20210307
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc
OBJDUMP = ${EMBTOOLPREFIX}-objdump
OBJCOPY = ${EMBTOOLPREFIX}-objcopy
```
### 5. Linux + XEMU
#### 1. 说明
- 内核及外设:`YuHeng 5-state RISC-V Core`
- 软件编译器:`gcc version 8.4.0 (T-HEAD RISCV Tools V1.10.5.1 B20210307)`
- 仿真环境:`XEMU`
*注意,不能定义 `PRINT_STDIO_SIM`,即只支持使用 UART 来重定向 xprintf *
#### 2. 操作
安装 curses 库
```
sudo apt-get update
sudo apt-get install -y libncurses-dev
```
修改测试程序编译工具的路径(文件路径:`sim/config.mk`
```
EMBTOOLPATH = /home/crazy/Tools/compiler/xuantie/v8.4.0/riscv64-elf-x86_64-20210307
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc
OBJDUMP = ${EMBTOOLPREFIX}-objdump
OBJCOPY = ${EMBTOOLPREFIX}-objcopy
```
## 四、使用说明
*注意,以下操作不区分 Windows 和 Linux 平台*
### 1. 编译测试程序
1. 打开 Terminal
2. 进入 `sim/simple`
3. 执行 `make build`,编译测试程序
- 在 Windows 平台中,还会在工程的根目录下生成 .mi 文件,用于固化 Gowin FPGA 的 rom IP
### 2. 编译 RTL
*注意,仅在 vcs 和 iverilog 仿真时使用*
1. 打开 Terminal
2. 进入 `sim/simple`
3. 执行 `make compile`,编译 RTL
4. 执行 `make build`,编译测试程序
5. 执行 `make sim`,进行仿真
6. 执行 `make wave`,查看波形
此外,可以使用 `make run`,等价于 `make compile && make build && make sim`
### 3. 编译 XEMU 并运行
1. 打开 Terminal
2. 进入 `sim/simple`
3. 执行 `make xemu`,先编译 XEMU然后编译测试程序并运行
*模拟器退出条件1. 通过 UART1 发送字节序列 0x1b 0x04*
*模拟器退出条件2. 键盘输入 Ctrl+b/B*
### 4. 使用 debugger
1. 进入 `scripts/debugger`
2. 运行 `debugger.py``debugger.exe`
- `debugger.exe` 通过 `pkgtool.bat` 脚本对 `debugger.py` 打包得到
debugger 支持的命令:
- `com`,扫描串口
- `com4`打开串口格式115200 N 8 1
```
This is a PuSH Terminal.
Help Menu:
----------------------------------------
~ - Switch mode.
q - Exit terminal.
r - Repeat last command.
help - (h) Show help menu.
cd - Switch to work path.
load - (ld) Load file.
download - (d) Download to target device.
go - (g) Control target device jump and run.
com - Scan valid serial port.
com* - Open target serial port.
```
*注意debugger 需要配合 Gowin FPGA 使用*
## 五、项目引用
> RISC-V 内核: git clone https://gitee.com/dengchow/yuheng-riscv-soc.git
> XEMU 模拟器: git clone https://gitee.com/dengchow/xemu.git
## 六、修改日志
- v1.0
- 创建项目并集成测试0:29 2024/3/10
## 七、维护
如果有任何疑问或者建议,欢迎在下方评论
ATONEMAN
2024/6/11

13
fpga_project/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.gprj
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*

View File

@ -0,0 +1,34 @@
<?xml version="1" encoding="UTF-8"?>
<!DOCTYPE gowin-fpga-project>
<Project>
<Template>FPGA</Template>
<Version>5</Version>
<Device name="GW1NR-9C" pn="GW1NR-LV9QN88PC6/I5">gw1nr9c-004</Device>
<FileList>
<File path="src/ipdefs/gowin_dpb_32x8k/gowin_dpb_32x8k.v" type="file.verilog" enable="1"/>
<File path="src/ipdefs/gowin_dpb_8x4k/gowin_dpb_8x4k.v" type="file.verilog" enable="1"/>
<File path="src/ipdefs/gowin_rpll/gowin_rpll.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_clint.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_csr.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_exu.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_exu_div.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_exu_mul.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_idu.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_mau.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_pcgen.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_rtu.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_top.v" type="file.verilog" enable="1"/>
<File path="src/rtl/core/pa_core_xreg.v" type="file.verilog" enable="1"/>
<File path="src/rtl/pa_chip_param.v" type="file.verilog" enable="1"/>
<File path="src/rtl/pa_chip_top.v" type="file.verilog" enable="1"/>
<File path="src/rtl/perips/pa_perips_gpio.v" type="file.verilog" enable="1"/>
<File path="src/rtl/perips/pa_perips_tcm.v" type="file.verilog" enable="1"/>
<File path="src/rtl/perips/pa_perips_tcm2.v" type="file.verilog" enable="1"/>
<File path="src/rtl/perips/pa_perips_timer.v" type="file.verilog" enable="1"/>
<File path="src/rtl/perips/pa_perips_uart.v" type="file.verilog" enable="1"/>
<File path="src/rtl/soc/pa_soc_rbm.v" type="file.verilog" enable="1"/>
<File path="src/rtl/utils/pa_dff.v" type="file.verilog" enable="1"/>
<File path="src/fpga_project.cst" type="file.cst" enable="1"/>
<File path="src/fpga_project.sdc" type="file.sdc" enable="1"/>
</FileList>
</Project>

11
fpga_project/src/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
#*
#!*/
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*

20
fpga_project/src/design.f Normal file
View File

@ -0,0 +1,20 @@
+incdir+../../fpga_project/src/rtl
../../fpga_project/src/rtl/utils/pa_dff.v
../../fpga_project/src/rtl/core/pa_core_xreg.v
../../fpga_project/src/rtl/core/pa_core_csr.v
../../fpga_project/src/rtl/core/pa_core_pcgen.v
../../fpga_project/src/rtl/core/pa_core_idu.v
../../fpga_project/src/rtl/core/pa_core_exu_div.v
../../fpga_project/src/rtl/core/pa_core_exu_mul.v
../../fpga_project/src/rtl/core/pa_core_exu.v
../../fpga_project/src/rtl/core/pa_core_clint.v
../../fpga_project/src/rtl/core/pa_core_mau.v
../../fpga_project/src/rtl/core/pa_core_rtu.v
../../fpga_project/src/rtl/core/pa_core_top.v
../../fpga_project/src/rtl/perips/pa_perips_tcm.v
../../fpga_project/src/rtl/perips/pa_perips_tcm2.v
../../fpga_project/src/rtl/perips/pa_perips_timer.v
../../fpga_project/src/rtl/perips/pa_perips_uart.v
../../fpga_project/src/rtl/perips/pa_perips_gpio.v
../../fpga_project/src/rtl/soc/pa_soc_rbm.v
../../fpga_project/src/rtl/pa_chip_top.v

View File

@ -0,0 +1,64 @@
//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
//All rights reserved.
//File Title: Physical Constraints file
//GOWIN Version: 1.9.8.11 Education
//Part Number: GW1NR-LV9QN88PC6/I5
//Device: GW1NR-9
//Device Version: C
//Created Time: Sat 12 30 20:58:14 2023
IO_LOC "clk_i" 52;
IO_PORT "clk_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
IO_LOC "rst_n_i" 4;
IO_PORT "rst_n_i" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
IO_LOC "clk_o" 38;
IO_PORT "clk_o" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA15" 70;
IO_PORT "gpio_PA15" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA14" 71;
IO_PORT "gpio_PA14" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
IO_LOC "gpio_PA13" 72;
IO_PORT "gpio_PA13" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA12" 73;
IO_PORT "gpio_PA12" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA11" 74;
IO_PORT "gpio_PA11" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA10" 75;
IO_PORT "gpio_PA10" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3;
IO_LOC "gpio_PA9" 76;
IO_PORT "gpio_PA9" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA8" 77;
IO_PORT "gpio_PA8" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA7" 79;
IO_PORT "gpio_PA7" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA6" 80;
IO_PORT "gpio_PA6" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA5" 81;
IO_PORT "gpio_PA5" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA4" 82;
IO_PORT "gpio_PA4" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA3" 83;
IO_PORT "gpio_PA3" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=12 OPEN_DRAIN=OFF BANK_VCCIO=3.3;
IO_LOC "gpio_PA2" 84;
IO_PORT "gpio_PA2" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA1" 85;
IO_PORT "gpio_PA1" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;
IO_LOC "gpio_PA0" 86;
IO_PORT "gpio_PA0" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=12 OPEN_DRAIN=ON BANK_VCCIO=3.3;

View File

@ -0,0 +1,7 @@
//Copyright (C)2014-2024 GOWIN Semiconductor Corporation.
//All rights reserved.
//File Title: Timing Constraints file
//GOWIN Version: 1.9.8.11 Education
//Created Time: 2024-01-06 21:37:45
create_clock -name clk_i -period 37.037 -waveform {0 18.518} [get_ports {clk_i}]
create_clock -name clk_o -period 98.765 -waveform {0 49.383} [get_ports {clk_o}]

16
fpga_project/src/ipdefs/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.ipc
!*.v
*_tmp.v
# Step-3, untrack all in sub folders, which use their own .gitignore
#*/*

View File

@ -0,0 +1,24 @@
[General]
ipc_version=4
file=gowin_dpb_32x8k
module=Gowin_DPB_32x8k
target_device=gw1nr9c-004
type=ram_dpb
version=1.0
[Config]
Area=true
BYTE_SIZE=0
DEPTH_A=8192
DEPTH_B=8192
LANG=0
READ_A=0
READ_B=0
RESET_MODE=true
Speed=false
WIDTH_A=32
WIDTH_B=32
WRITE_A=0
WRITE_B=0
DIMENSION_MATCH=65
MEM_FILE=E:\\0_Project\\rep_mygit\\TraSH\\riscv-bootloader.mi

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
[General]
ipc_version=4
file=gowin_dpb_8x4k
module=Gowin_DPB_8x4k
target_device=gw1nr9c-004
type=ram_dpb
version=1.0
[Config]
Area=true
BYTE_SIZE=0
DEPTH_A=4096
DEPTH_B=4096
LANG=0
READ_A=0
READ_B=0
RESET_MODE=true
Speed=false
WIDTH_A=8
WIDTH_B=8
WRITE_A=0
WRITE_B=0

View File

@ -0,0 +1,99 @@
//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
//All rights reserved.
//File Title: IP file
//GOWIN Version: V1.9.8.11 Education
//Part Number: GW1NR-LV9QN88PC6/I5
//Device: GW1NR-9
//Device Version: C
//Created Time: Sat Jan 06 16:21:33 2024
module Gowin_DPB_8x4k (douta, doutb, clka, ocea, cea, reseta, wrea, clkb, oceb, ceb, resetb, wreb, ada, dina, adb, dinb);
output [7:0] douta;
output [7:0] doutb;
input clka;
input ocea;
input cea;
input reseta;
input wrea;
input clkb;
input oceb;
input ceb;
input resetb;
input wreb;
input [11:0] ada;
input [7:0] dina;
input [11:0] adb;
input [7:0] dinb;
wire [11:0] dpb_inst_0_douta_w;
wire [11:0] dpb_inst_0_doutb_w;
wire [11:0] dpb_inst_1_douta_w;
wire [11:0] dpb_inst_1_doutb_w;
wire gw_gnd;
assign gw_gnd = 1'b0;
DPB dpb_inst_0 (
.DOA({dpb_inst_0_douta_w[11:0],douta[3:0]}),
.DOB({dpb_inst_0_doutb_w[11:0],doutb[3:0]}),
.CLKA(clka),
.OCEA(ocea),
.CEA(cea),
.RESETA(reseta),
.WREA(wrea),
.CLKB(clkb),
.OCEB(oceb),
.CEB(ceb),
.RESETB(resetb),
.WREB(wreb),
.BLKSELA({gw_gnd,gw_gnd,gw_gnd}),
.BLKSELB({gw_gnd,gw_gnd,gw_gnd}),
.ADA({ada[11:0],gw_gnd,gw_gnd}),
.DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[3:0]}),
.ADB({adb[11:0],gw_gnd,gw_gnd}),
.DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[3:0]})
);
defparam dpb_inst_0.READ_MODE0 = 1'b0;
defparam dpb_inst_0.READ_MODE1 = 1'b0;
defparam dpb_inst_0.WRITE_MODE0 = 2'b00;
defparam dpb_inst_0.WRITE_MODE1 = 2'b00;
defparam dpb_inst_0.BIT_WIDTH_0 = 4;
defparam dpb_inst_0.BIT_WIDTH_1 = 4;
defparam dpb_inst_0.BLK_SEL_0 = 3'b000;
defparam dpb_inst_0.BLK_SEL_1 = 3'b000;
defparam dpb_inst_0.RESET_MODE = "SYNC";
DPB dpb_inst_1 (
.DOA({dpb_inst_1_douta_w[11:0],douta[7:4]}),
.DOB({dpb_inst_1_doutb_w[11:0],doutb[7:4]}),
.CLKA(clka),
.OCEA(ocea),
.CEA(cea),
.RESETA(reseta),
.WREA(wrea),
.CLKB(clkb),
.OCEB(oceb),
.CEB(ceb),
.RESETB(resetb),
.WREB(wreb),
.BLKSELA({gw_gnd,gw_gnd,gw_gnd}),
.BLKSELB({gw_gnd,gw_gnd,gw_gnd}),
.ADA({ada[11:0],gw_gnd,gw_gnd}),
.DIA({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dina[7:4]}),
.ADB({adb[11:0],gw_gnd,gw_gnd}),
.DIB({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,dinb[7:4]})
);
defparam dpb_inst_1.READ_MODE0 = 1'b0;
defparam dpb_inst_1.READ_MODE1 = 1'b0;
defparam dpb_inst_1.WRITE_MODE0 = 2'b00;
defparam dpb_inst_1.WRITE_MODE1 = 2'b00;
defparam dpb_inst_1.BIT_WIDTH_0 = 4;
defparam dpb_inst_1.BIT_WIDTH_1 = 4;
defparam dpb_inst_1.BLK_SEL_0 = 3'b000;
defparam dpb_inst_1.BLK_SEL_1 = 3'b000;
defparam dpb_inst_1.RESET_MODE = "SYNC";
endmodule //Gowin_DPB_8x4k

View File

@ -0,0 +1,24 @@
[General]
ipc_version=4
file=gowin_rpll
module=Gowin_rPLL
target_device=gw1nr9c-004
type=clock_rpll
version=1.0
[Config]
CKLOUTD3=false
CLKFB_SOURCE=0
CLKIN_FREQ=27
CLKOUTD=false
CLKOUTP=false
CLKOUT_BYPASS=false
CLKOUT_DIVIDE_DYN=true
CLKOUT_FREQ=10.125
CLKOUT_TOLERANCE=0
DYNAMIC=false
LANG=0
LOCK_EN=true
MODE_GENERAL=true
PLL_PWD=false
RESET_PLL=true

View File

@ -0,0 +1,65 @@
//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
//All rights reserved.
//File Title: IP file
//GOWIN Version: V1.9.8.11 Education
//Part Number: GW1NR-LV9QN88PC6/I5
//Device: GW1NR-9
//Device Version: C
//Created Time: Sat Jan 06 21:34:57 2024
module Gowin_rPLL (clkout, lock, reset, clkin);
output clkout;
output lock;
input reset;
input clkin;
wire clkoutp_o;
wire clkoutd_o;
wire clkoutd3_o;
wire gw_gnd;
assign gw_gnd = 1'b0;
rPLL rpll_inst (
.CLKOUT(clkout),
.LOCK(lock),
.CLKOUTP(clkoutp_o),
.CLKOUTD(clkoutd_o),
.CLKOUTD3(clkoutd3_o),
.RESET(reset),
.RESET_P(gw_gnd),
.CLKIN(clkin),
.CLKFB(gw_gnd),
.FBDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
.IDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
.ODSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
.PSDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
.DUTYDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
.FDLY({gw_gnd,gw_gnd,gw_gnd,gw_gnd})
);
defparam rpll_inst.FCLKIN = "27";
defparam rpll_inst.DYN_IDIV_SEL = "false";
defparam rpll_inst.IDIV_SEL = 7;
defparam rpll_inst.DYN_FBDIV_SEL = "false";
defparam rpll_inst.FBDIV_SEL = 2;
defparam rpll_inst.DYN_ODIV_SEL = "false";
defparam rpll_inst.ODIV_SEL = 48;
defparam rpll_inst.PSDA_SEL = "0000";
defparam rpll_inst.DYN_DA_EN = "false";
defparam rpll_inst.DUTYDA_SEL = "1000";
defparam rpll_inst.CLKOUT_FT_DIR = 1'b1;
defparam rpll_inst.CLKOUTP_FT_DIR = 1'b1;
defparam rpll_inst.CLKOUT_DLY_STEP = 0;
defparam rpll_inst.CLKOUTP_DLY_STEP = 0;
defparam rpll_inst.CLKFB_SEL = "internal";
defparam rpll_inst.CLKOUT_BYPASS = "false";
defparam rpll_inst.CLKOUTP_BYPASS = "false";
defparam rpll_inst.CLKOUTD_BYPASS = "false";
defparam rpll_inst.DYN_SDIV_SEL = 2;
defparam rpll_inst.CLKOUTD_SRC = "CLKOUT";
defparam rpll_inst.CLKOUTD3_SRC = "CLKOUT";
defparam rpll_inst.DEVICE = "GW1NR-9C";
endmodule //Gowin_rPLL

13
fpga_project/src/rtl/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.v
# Step-3, untrack all in sub folders, which use their own .gitignore
#*/*

View File

@ -0,0 +1,302 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-14 Lyons v3.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_clint (
input wire clk_i,
input wire rst_n_i,
input wire inst_set_i, // indicate instruction set, [0], only support rv32i yet
input wire [2:0] inst_func_i, // indicate instruction func, [6:4], only 3-bits
input wire [`ADDR_BUS_WIDTH-1:0] pc_i,
input wire [`DATA_BUS_WIDTH-1:0] inst_i,
input wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_i,
input wire [`DATA_BUS_WIDTH-1:0] csr_mepc_i,
input wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_i,
input wire irq_i,
input wire jump_flag_i,
input wire hold_flag_i,
output wire [`CSR_BUS_WIDTH-1:0] csr_waddr_o,
output wire csr_waddr_vld_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_wdata_o,
output wire hold_flag_o,
output wire jump_flag_o,
output wire [`DATA_BUS_WIDTH-1:0] jump_addr_o
);
// value of 'int_state'
localparam INT_STATE_IDLE = 2'd0;
localparam INT_STATE_MCALL = 2'd1;
localparam INT_STATE_MRET = 2'd2;
// value of 'int_type'
localparam INT_TYPE_NONE = 2'b00;
localparam INT_TYPE_EXCRPTION = 2'b01;
localparam INT_TYPE_INTERRUPT = 2'b10;
localparam INT_TYPE_SOFTINT = 2'b11;
// value of 'csr_state'
localparam CSR_STATE_IDLE = 3'd0;
localparam CSR_STATE_WAIT = 3'd1;
localparam CSR_STATE_MEPC = 3'd2;
localparam CSR_STATE_MSTATUS = 3'd3;
localparam CSR_STATE_MCAUSE = 3'd4;
localparam CSR_STATE_MRET = 3'd5;
reg [1:0] int_state;
reg [1:0] int_type;
reg [2:0] csr_state;
wire inst_set_rvi;
assign inst_set_rvi = inst_set_i;
wire global_int_en;
wire global_int_si;
assign global_int_en = csr_mstatus_i[3]; // MIE
assign global_int_si = csr_mstatus_i[31]; // SINT
// 'op_xxx' is equal to zero when it is Non-ecall/ebreak/mret inst
wire op_ecall;
wire op_ebreak;
wire op_mret;
assign op_ecall = 0; //inst_set_rvi && inst_func_i[2]; // to inst_func_i[6]
assign op_ebreak = inst_set_rvi && inst_func_i[1]; // to inst_func_i[5]
assign op_mret = inst_set_rvi && inst_func_i[0]; // to inst_func_i[4]
wire [1:0] irq_1r;
pa_dff_rst_0 #(2) dff_irq_1r (clk_i, rst_n_i, `VALID, {irq_1r[0], irq_i}, irq_1r);
// 'irq_vld' is valid during the csr-handle cycle
wire irq_vld;
reg irq_vld_t;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
irq_vld_t <= `INVALID;
end
else begin
if (int_state == INT_STATE_IDLE) begin
irq_vld_t <= `INVALID;
end
else begin
irq_vld_t <= irq_vld;
end
end
end
assign irq_vld = (irq_vld_t)
|| (~irq_1r[1] && irq_1r[0]); // posedge of irq_i
always @ (*) begin
if (!rst_n_i) begin
int_state <= INT_STATE_IDLE;
int_type <= INT_TYPE_NONE;
end
else begin
if (op_mret) begin
int_state <= INT_STATE_MRET;
int_type <= INT_TYPE_EXCRPTION;
end
else if (op_ecall || op_ebreak) begin
int_state <= INT_STATE_MCALL;
int_type <= INT_TYPE_EXCRPTION;
end
else if (global_int_en && irq_vld) begin
int_state <= INT_STATE_MCALL;
int_type <= INT_TYPE_INTERRUPT;
end
else if (global_int_en && global_int_si) begin
int_state <= INT_STATE_MCALL;
int_type <= INT_TYPE_SOFTINT;
end
else begin
int_state <= INT_STATE_IDLE;
int_type <= INT_TYPE_NONE;
end
end
end
wire jump_addr_sel;
assign jump_addr_sel = ~(|inst_i[`DATA_BUS_WIDTH-1:0]);
wire [`DATA_BUS_WIDTH-1:0] inst_addr;
wire [`DATA_BUS_WIDTH-1:0] jump_addr;
assign inst_addr[`DATA_BUS_WIDTH-1:0] = pc_i[`DATA_BUS_WIDTH-1:0] + 32'hffff_fffc; // -4
assign jump_addr[`DATA_BUS_WIDTH-1:0] = pc_i[`DATA_BUS_WIDTH-1:0]; // -0
wire [`DATA_BUS_WIDTH-1:0] break_addr_soft;
wire [`DATA_BUS_WIDTH-1:0] break_addr_ext;
assign break_addr_soft[`DATA_BUS_WIDTH-1:0] = {32{int_type[0] & op_ecall }} & (jump_addr_sel ? jump_addr : inst_addr)
| {32{int_type[0] & op_ebreak }} & (jump_addr_sel ? jump_addr : inst_addr);
assign break_addr_ext[`DATA_BUS_WIDTH-1:0] = {32{int_type[1] }} & (jump_addr_sel ? jump_addr : inst_addr);
wire [`DATA_BUS_WIDTH-1:0] break_cause_soft;
wire [`DATA_BUS_WIDTH-1:0] break_cause_ext;
assign break_cause_soft[`DATA_BUS_WIDTH-1:0] = {32{int_type[0] & op_ecall }} & 32'd11
| {32{int_type[0] & op_ebreak }} & 32'd3;
assign break_cause_ext[`DATA_BUS_WIDTH-1:0] = {32{int_type[1] & ~int_type[0]}} & 32'h8000_0003
| {32{int_type[1] & int_type[0]}} & 32'h8000_0004;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
csr_state <= CSR_STATE_IDLE;
end
else begin
case (csr_state)
CSR_STATE_IDLE ,
CSR_STATE_WAIT : begin
case (int_state)
INT_STATE_MCALL : begin
if (jump_flag_i || hold_flag_i) begin
csr_state <= CSR_STATE_WAIT;
end
else begin
csr_state <= CSR_STATE_MEPC;
end
end
INT_STATE_MRET : begin
csr_state <= CSR_STATE_MRET;
end
endcase
end
CSR_STATE_MEPC : csr_state <= (jump_flag_i ? CSR_STATE_MEPC : CSR_STATE_MSTATUS);
CSR_STATE_MSTATUS : csr_state <= CSR_STATE_MCAUSE;
CSR_STATE_MCAUSE : csr_state <= CSR_STATE_IDLE;
CSR_STATE_MRET : csr_state <= CSR_STATE_IDLE;
default : begin
csr_state <= CSR_STATE_IDLE;
end
endcase
end
end
wire [`DATA_BUS_WIDTH-1:0] break_cause;
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_break_cause (clk_i, rst_n_i,
(int_state == INT_STATE_MCALL) && !jump_flag_i && !hold_flag_i,
(break_cause_soft | break_cause_ext), {`DATA_BUS_WIDTH{1'b0}},
break_cause);
reg [`CSR_BUS_WIDTH-1:0] csr_waddr;
reg csr_waddr_vld;
reg [`DATA_BUS_WIDTH-1:0] csr_wdata;
always @ (*) begin
case (csr_state)
CSR_STATE_MEPC : begin
csr_waddr <= {20'h0, `CSR_MEPC};
csr_waddr_vld <= `VALID;
csr_wdata <= break_addr_soft
| break_addr_ext;
end
CSR_STATE_MSTATUS : begin
csr_waddr <= {20'h0, `CSR_MSTATUS};
csr_waddr_vld <= `VALID;
csr_wdata <= {csr_mstatus_i[31:8], csr_mstatus_i[3], csr_mstatus_i[6:4], 1'b0, csr_mstatus_i[2:0]};
end
CSR_STATE_MCAUSE : begin
csr_waddr <= {20'h0, `CSR_MCAUSE};
csr_waddr_vld <= `VALID;
csr_wdata <= break_cause;
end
CSR_STATE_MRET : begin
csr_waddr <= {20'h0, `CSR_MSTATUS};
csr_waddr_vld <= `VALID;
csr_wdata <= {csr_mstatus_i[31:8], 1'b0, csr_mstatus_i[6:4], csr_mstatus_i[7], csr_mstatus_i[2:0]};
end
default : begin
csr_waddr <= `ZERO_WORD;
csr_waddr_vld <= `INVALID;
csr_wdata <= `ZERO_WORD;
end
endcase
end
wire [`DATA_BUS_WIDTH-1:0] csr_mtvec;
wire [`DATA_BUS_WIDTH-1:0] csr_mepc;
assign csr_mtvec[`DATA_BUS_WIDTH-1:0] = (break_cause == 32'h8000_0004) ? (csr_mtvec_i[`DATA_BUS_WIDTH-1:0] + 32'h4)
: csr_mtvec_i[`DATA_BUS_WIDTH-1:0];
assign csr_mepc[`DATA_BUS_WIDTH-1:0] = csr_mepc_i[`DATA_BUS_WIDTH-1:0];
reg int_jump_flag;
reg [`DATA_BUS_WIDTH-1:0] int_jump_addr;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
int_jump_flag <= `INVALID;
int_jump_addr <= `ZERO_WORD;
end
else begin
case (csr_state)
CSR_STATE_MCAUSE : begin
int_jump_flag <= `VALID;
int_jump_addr <= csr_mtvec;
end
CSR_STATE_MRET : begin
int_jump_flag <= `VALID;
int_jump_addr <= csr_mepc;
end
default : begin
int_jump_flag <= `INVALID;
int_jump_addr <= `ZERO_WORD;
end
endcase
end
end
assign csr_waddr_o[`CSR_BUS_WIDTH-1:0] = csr_waddr[`CSR_BUS_WIDTH-1:0];
assign csr_waddr_vld_o = csr_waddr_vld;
assign csr_wdata_o[`DATA_BUS_WIDTH-1:0] = csr_wdata[`DATA_BUS_WIDTH-1:0];
assign hold_flag_o = (csr_state != CSR_STATE_IDLE);
assign jump_flag_o = int_jump_flag;
assign jump_addr_o[`DATA_BUS_WIDTH-1:0] = int_jump_addr[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_csr (
input wire clk_i,
input wire rst_n_i,
output wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_mepc_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_o,
input wire [`CSR_BUS_WIDTH-1:0] csr_raddr_i,
input wire [`CSR_BUS_WIDTH-1:0] csr_waddr_i,
input wire csr_waddr_vld_i,
input wire [`DATA_BUS_WIDTH-1:0] csr_wdata_i,
output wire [`DATA_BUS_WIDTH-1:0] csr_rdata_o
);
reg [`DATA_BUS_WIDTH-1:0] _mtvec; // Machine Trap Vector
reg [`DATA_BUS_WIDTH-1:0] _mepc; // Machine Exception PC
reg [`DATA_BUS_WIDTH-1:0] _mcause; // Machine Exception Cause
reg [`DATA_BUS_WIDTH-1:0] _mie; // Machine Interrupt Enable
reg [`DATA_BUS_WIDTH-1:0] _mip; // Machine Interrupt Pending
reg [`DATA_BUS_WIDTH-1:0] _mtval; // Machine Trap Value
reg [`DATA_BUS_WIDTH-1:0] _mscratch; // Machine Scratch
reg [`DATA_BUS_WIDTH-1:0] _mscratchcswl; // Machine Scratch
reg [`DATA_BUS_WIDTH-1:0] _mstatus; // Machine Status
reg [63:0] _cycle; // Machine Cycle
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_cycle <= 64'h0;
end
else begin
_cycle <= _cycle + 64'h1;
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_mtvec <= 32'h0;
_mepc <= 32'h0;
_mcause <= 32'h0;
_mie <= 32'h0;
_mip <= 32'h0;
_mtval <= 32'h0;
_mscratch <= 32'h0;
_mstatus <= 32'h0000_0060; // MPP=11
end
else if (csr_waddr_vld_i) begin
case (csr_waddr_i[11:0])
`CSR_MTVEC : _mtvec <= csr_wdata_i;
`CSR_MEPC : _mepc <= csr_wdata_i;
`CSR_MCAUSE : _mcause <= csr_wdata_i;
`CSR_MIE : _mie <= csr_wdata_i;
`CSR_MIP : _mip <= csr_wdata_i;
`CSR_MTVAL : _mtval <= csr_wdata_i;
`CSR_MSCRATCH : _mscratch <= csr_wdata_i;
`CSR_MSCRATCHCSWL : _mscratchcswl <= csr_wdata_i;
`CSR_MSTATUS : _mstatus <= csr_wdata_i;
endcase
end
end
reg [`DATA_BUS_WIDTH-1:0] _csr;
always @ (*) begin
_csr = `ZERO_WORD;
case (csr_raddr_i[11:0])
`CSR_MTVEC : _csr = _mtvec;
`CSR_MEPC : _csr = _mepc;
`CSR_MCAUSE : _csr = _mcause;
`CSR_MIE : _csr = _mie;
`CSR_MIP : _csr = _mip;
`CSR_MTVAL : _csr = _mtval;
`CSR_MSCRATCH : _csr = _mscratch;
`CSR_MSCRATCHCSWL : _csr = _mscratchcswl;
`CSR_MSTATUS : _csr = _mstatus;
`CSR_CYCLEH : _csr = _cycle[63:32];
`CSR_CYCLE : _csr = _cycle[31: 0];
endcase
end
assign csr_mtvec_o[`DATA_BUS_WIDTH-1:0] = _mtvec[`DATA_BUS_WIDTH-1:0];
assign csr_mepc_o[`DATA_BUS_WIDTH-1:0] = _mepc[`DATA_BUS_WIDTH-1:0];
assign csr_mstatus_o[`DATA_BUS_WIDTH-1:0] = _mstatus[`DATA_BUS_WIDTH-1:0];
assign csr_rdata_o[`DATA_BUS_WIDTH-1:0] = _csr[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,492 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-14 Lyons v3.0, add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_exu (
input wire clk_i,
input wire rst_n_i,
input wire [1:0] inst_set_i, // indicate instruction set, [1:0], only support rv32im yet
input wire [`INST_FUNC_WIDTH-1:0] inst_func_i,
input wire [`DATA_BUS_WIDTH-1:0] pc_i,
input wire [`DATA_BUS_WIDTH-1:0] reg1_rdata_i,
input wire [`DATA_BUS_WIDTH-1:0] reg2_rdata_i,
input wire [19:0] uimm_i, // immediate data, [19:0], only 20-bits
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
input wire reg_waddr_vld_i,
input wire [`DATA_BUS_WIDTH-1:0] csr_rdata_i,
output wire csr_waddr_vld_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_wdata_o,
output wire mem_en_o,
output wire hold_flag_o,
output wire jump_flag_o,
output wire [`DATA_BUS_WIDTH-1:0] jump_addr_o,
output wire [`REG_BUS_WIDTH-1:0] reg_waddr_o,
output wire reg_waddr_vld_o,
output wire [`DATA_BUS_WIDTH-1:0] iresult_o,
output wire iresult_vld_o
);
wire inst_set_rvi;
wire inst_set_rvm;
assign inst_set_rvi = inst_set_i[0];
assign inst_set_rvm = inst_set_i[1];
wire subop_unsign;
wire subop_sign;
wire subop_immv;
wire subop_regv;
wire subop_eq;
wire subop_ne;
wire subop_lt;
wire subop_gt;
assign subop_unsign = inst_func_i[31];
assign subop_sign = !inst_func_i[31];
assign subop_immv = inst_func_i[30];
assign subop_regv = !inst_func_i[30];
assign subop_eq = inst_func_i[27];
assign subop_ne = inst_func_i[26];
assign subop_lt = inst_func_i[25];
assign subop_gt = inst_func_i[24];
wire op_add;
wire op_sub;
wire op_sll;
wire op_srl;
wire op_sra;
wire op_or;
wire op_and;
wire op_xor;
wire op_slt;
wire op_load;
wire op_store;
wire op_fence;
wire op_b;
wire op_jal;
wire op_jalr;
wire op_auipc;
wire op_lui;
wire op_ecall;
wire op_ebrea;
wire op_mret;
wire op_wfi;
wire op_csrrw;
wire op_csrrs;
wire op_csrrc;
wire op_mul;
wire op_div;
wire op_rem;
assign op_add = inst_set_rvi && inst_func_i[23];
assign op_sub = inst_set_rvi && inst_func_i[22];
assign op_sll = inst_set_rvi && inst_func_i[21];
assign op_srl = inst_set_rvi && inst_func_i[20];
assign op_sra = inst_set_rvi && inst_func_i[19];
assign op_or = inst_set_rvi && inst_func_i[18];
assign op_and = inst_set_rvi && inst_func_i[17];
assign op_xor = inst_set_rvi && inst_func_i[16];
assign op_slt = inst_set_rvi && inst_func_i[15];
assign op_load = inst_set_rvi && inst_func_i[14];
assign op_store = inst_set_rvi && inst_func_i[13];
assign op_fence = inst_set_rvi && inst_func_i[12];
assign op_b = inst_set_rvi && inst_func_i[11];
assign op_jal = inst_set_rvi && inst_func_i[10];
assign op_jalr = inst_set_rvi && inst_func_i[ 9];
assign op_auipc = inst_set_rvi && inst_func_i[ 8];
assign op_lui = inst_set_rvi && inst_func_i[ 7];
assign op_ecall = inst_set_rvi && inst_func_i[ 6];
assign op_ebrea = inst_set_rvi && inst_func_i[ 5];
assign op_mret = inst_set_rvi && inst_func_i[ 4];
assign op_wfi = inst_set_rvi && inst_func_i[ 3];
assign op_csrrw = inst_set_rvi && inst_func_i[ 2];
assign op_csrrs = inst_set_rvi && inst_func_i[ 1];
assign op_csrrc = inst_set_rvi && inst_func_i[ 0];
assign op_mul = inst_set_rvm && inst_func_i[23];
assign op_div = inst_set_rvm && inst_func_i[22];
assign op_rem = inst_set_rvm && inst_func_i[21];
wire [`DATA_BUS_WIDTH-1:0] inst_addr;
assign inst_addr[`DATA_BUS_WIDTH-1:0] = pc_i[`DATA_BUS_WIDTH-1:0] + 32'hffff_fff8; // -8, back 2-inst
wire [`DATA_BUS_WIDTH-1:0] op_uimm5_zero;
assign op_uimm5_zero = {{27{1'b0}}, uimm_i[4:0]};
wire [`DATA_BUS_WIDTH-1:0] op_uimm12_zero;
wire [`DATA_BUS_WIDTH-1:0] op_uimm12_sign;
assign op_uimm12_zero = {{20{1'b0}}, uimm_i[11:0]};
assign op_uimm12_sign = {{20{uimm_i[11]}}, uimm_i[11:0]};
wire [`DATA_BUS_WIDTH-1:0] op1_data_1;
wire [`DATA_BUS_WIDTH-1:0] op1_data_2;
assign op1_data_1 = {32{op_csrrw || op_csrrs || op_csrrc}}
& (subop_immv ? op_uimm5_zero
: reg1_rdata_i);
assign op1_data_2 = {32{!op_csrrw && !op_csrrs && !op_csrrc}}
& reg1_rdata_i;
wire [`DATA_BUS_WIDTH-1:0] op2_data_1;
wire [`DATA_BUS_WIDTH-1:0] op2_data_2;
wire [`DATA_BUS_WIDTH-1:0] op2_data_3;
assign op2_data_1 = {32{op_slt || op_load || op_store}}
& (subop_immv ? op_uimm12_sign
: reg2_rdata_i);
assign op2_data_2 = {32{op_csrrw || op_csrrs || op_csrrc}}
& `ZERO_WORD;
assign op2_data_3 = {32{!op_slt && !op_load && !op_store && !op_csrrw && !op_csrrs && !op_csrrc}}
& (subop_immv ? subop_unsign ? op_uimm12_zero
: op_uimm12_sign
: reg2_rdata_i);
wire [`DATA_BUS_WIDTH-1:0] op1_data;
wire [`DATA_BUS_WIDTH-1:0] op2_data;
assign op1_data = op1_data_1
| op1_data_2;
assign op2_data = op2_data_1
| op2_data_2
| op2_data_3;
wire [`DATA_BUS_WIDTH-1:0] iresult_add;
wire [`DATA_BUS_WIDTH-1:0] iresult_sub;
wire [`DATA_BUS_WIDTH-1:0] iresult_sll;
wire [`DATA_BUS_WIDTH-1:0] iresult_srl;
wire [`DATA_BUS_WIDTH-1:0] iresult_sra;
wire [`DATA_BUS_WIDTH-1:0] iresult_or;
wire [`DATA_BUS_WIDTH-1:0] iresult_and;
wire [`DATA_BUS_WIDTH-1:0] iresult_xor;
wire [`DATA_BUS_WIDTH-1:0] iresult_slt;
wire [`DATA_BUS_WIDTH-1:0] iresult_mem;
wire [`DATA_BUS_WIDTH-1:0] iresult_jalx;
wire [`DATA_BUS_WIDTH-1:0] iresult_auipc;
wire [`DATA_BUS_WIDTH-1:0] iresult_lui;
wire [`DATA_BUS_WIDTH-1:0] iresult_csrw;
wire [`DATA_BUS_WIDTH-1:0] iresult_csrs;
wire [`DATA_BUS_WIDTH-1:0] iresult_csrc;
wire [`DATA_BUS_WIDTH-1:0] result_pc_bxx;
wire [`DATA_BUS_WIDTH-1:0] result_pc_jalx;
assign iresult_add = op1_data + op2_data;
assign iresult_sub = op1_data + (~op2_data + 32'h1);
assign iresult_sll = op1_data << op2_data[4:0]; // mux circuit
assign iresult_srl = op1_data >> op2_data[4:0]; // mux circuit
assign iresult_sra = iresult_srl
| ~(32'hffff_ffff >> op2_data[4:0]) & {32{op1_data[31]}};
assign iresult_or = op1_data | op2_data;
assign iresult_and = op1_data & op2_data;
assign iresult_xor = op1_data ^ op2_data;
wire [`DATA_BUS_WIDTH:0] iresult_subs;
wire [`DATA_BUS_WIDTH:0] iresult_subu;
wire iresult_subs_zero;
wire iresult_subu_zero;
assign iresult_subs = {op1_data[31], op1_data[31:0]}
+ (~{op2_data[31], op2_data[31:0]} + 33'h1);
assign iresult_subu = {1'b0, op1_data[31:0]}
+ (~{1'b0, op2_data[31:0]} + 33'h1);
assign iresult_subs_zero = ~(|iresult_subs[32:0]);
assign iresult_subu_zero = ~(|iresult_subu[32:0]);
assign iresult_slt = subop_unsign ? ((iresult_subu[32] && !iresult_subu_zero) ? 32'h1 : 32'h0)
: ((iresult_subs[32] && !iresult_subs_zero) ? 32'h1 : 32'h0);
assign iresult_mem = op1_data + op2_data;
wire op1_eq_op2;
wire op1_ne_op2;
wire op1_lt_op2;
wire op1_ge_op2;
assign op1_eq_op2 = subop_eq && iresult_subs_zero;
assign op1_ne_op2 = subop_ne && !iresult_subs_zero;
assign op1_lt_op2 = subop_lt && iresult_subs[32];
assign op1_ge_op2 = subop_gt && !iresult_subs[32];
wire op1_ltu_op2;
wire op1_geu_op2;
assign op1_ltu_op2 = subop_lt && iresult_subu[32];
assign op1_geu_op2 = subop_gt && !iresult_subu[32];
wire bxx_valid;
assign bxx_valid = subop_sign && (op1_eq_op2 || op1_ne_op2 || op1_lt_op2 || op1_ge_op2)
|| subop_unsign && (op1_ltu_op2 || op1_geu_op2);
assign result_pc_bxx = inst_addr + {{19{uimm_i[11]}}, uimm_i[11:0], 1'b0};
assign result_pc_jalx = {32{op_jalr}} & ( (op1_data + {{20{uimm_i[11]}}, uimm_i[11:0]}) & 32'hffff_fffe )
| {32{op_jal }} & ( inst_addr + {{11{uimm_i[11]}}, uimm_i[19:0], 1'b0} );
assign iresult_jalx = inst_addr + 32'h4;
assign iresult_auipc = inst_addr + {uimm_i[19:0], 12'b0};
assign iresult_lui = {uimm_i[19:0], 12'b0};
assign iresult_csrw = op1_data;
assign iresult_csrs = csr_rdata_i | op1_data;
assign iresult_csrc = csr_rdata_i & ~op1_data;
reg [`DATA_BUS_WIDTH-1:0] iresult_i_final;
always @ (*) begin
iresult_i_final = `ZERO_WORD;
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
`INST_FUNC_ADD : iresult_i_final = iresult_add;
`INST_FUNC_SUB : iresult_i_final = iresult_sub;
`INST_FUNC_SLL : iresult_i_final = iresult_sll;
`INST_FUNC_SRL : iresult_i_final = iresult_srl;
`INST_FUNC_SRA : iresult_i_final = iresult_sra;
`INST_FUNC_OR : iresult_i_final = iresult_or;
`INST_FUNC_AND : iresult_i_final = iresult_and;
`INST_FUNC_XOR : iresult_i_final = iresult_xor;
`INST_FUNC_SLT : iresult_i_final = iresult_slt;
`INST_FUNC_LOAD : iresult_i_final = iresult_mem;
`INST_FUNC_STORE : iresult_i_final = iresult_mem;
`INST_FUNC_FENCE : iresult_i_final = `ZERO_WORD; // not support yet
`INST_FUNC_B : iresult_i_final = `ZERO_WORD;
`INST_FUNC_JAL : iresult_i_final = iresult_jalx;
`INST_FUNC_JALR : iresult_i_final = iresult_jalx;
`INST_FUNC_AUIPC : iresult_i_final = iresult_auipc;
`INST_FUNC_LUI : iresult_i_final = iresult_lui;
`INST_FUNC_WFI : iresult_i_final = `ZERO_WORD; // not support yet
`INST_FUNC_CSRRW : iresult_i_final = csr_rdata_i;
`INST_FUNC_CSRRS : iresult_i_final = csr_rdata_i;
`INST_FUNC_CSRRC : iresult_i_final = csr_rdata_i;
endcase
end
reg iresult_i_vld;
always @ (*) begin
iresult_i_vld = `INVALID;
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
`INST_FUNC_ADD : iresult_i_vld = `VALID;
`INST_FUNC_SUB : iresult_i_vld = `VALID;
`INST_FUNC_SLL : iresult_i_vld = `VALID;
`INST_FUNC_SRL : iresult_i_vld = `VALID;
`INST_FUNC_SRA : iresult_i_vld = `VALID;
`INST_FUNC_OR : iresult_i_vld = `VALID;
`INST_FUNC_AND : iresult_i_vld = `VALID;
`INST_FUNC_XOR : iresult_i_vld = `VALID;
`INST_FUNC_SLT : iresult_i_vld = `VALID;
`INST_FUNC_LOAD : iresult_i_vld = `VALID;
`INST_FUNC_STORE : iresult_i_vld = `VALID;
`INST_FUNC_FENCE : iresult_i_vld = `INVALID; // not support yet
`INST_FUNC_B : iresult_i_vld = `VALID;
`INST_FUNC_JAL : iresult_i_vld = `VALID;
`INST_FUNC_JALR : iresult_i_vld = `VALID;
`INST_FUNC_AUIPC : iresult_i_vld = `VALID;
`INST_FUNC_LUI : iresult_i_vld = `VALID;
`INST_FUNC_WFI : iresult_i_vld = `INVALID; //not support yet
`INST_FUNC_CSRRW : iresult_i_vld = `VALID;
`INST_FUNC_CSRRS : iresult_i_vld = `VALID;
`INST_FUNC_CSRRC : iresult_i_vld = `VALID;
endcase
end
// rv32m: mul process
wire subop_unsign_u1;
wire subop_unsign_u2;
wire subop_high;
wire subop_low;
assign subop_unsign_u1 = inst_func_i[31] & inst_func_i[28];
assign subop_unsign_u2 = inst_func_i[31] & inst_func_i[29];
assign subop_high = inst_func_i[30];
assign subop_low = !inst_func_i[30];
wire [`DATA_BUS_WIDTH-1:0] op1_mul_data;
wire [`DATA_BUS_WIDTH-1:0] op2_mul_data;
assign op1_mul_data = (~subop_unsign_u1 & reg1_rdata_i[31]) ? (~reg1_rdata_i + 32'b1)
: ( reg1_rdata_i);
assign op2_mul_data = (~subop_unsign_u2 & reg2_rdata_i[31]) ? (~reg2_rdata_i + 32'b1)
: ( reg2_rdata_i);
wire iresult_mul_sign;
assign iresult_mul_sign = (~subop_unsign_u1 & reg1_rdata_i[31])
^ (~subop_unsign_u2 & reg2_rdata_i[31]);
wire [63:0] iresult_mul;
pa_core_exu_mul u_pa_core_exu_mul (
.data1_i (op1_mul_data),
.data2_i (op2_mul_data),
.sign_i (iresult_mul_sign),
.data_o (iresult_mul)
);
// rv32m: div process
wire [`DATA_BUS_WIDTH-1:0] op1_div_data;
wire [`DATA_BUS_WIDTH-1:0] op2_div_data;
assign op1_div_data = op1_mul_data;
assign op2_div_data = op2_mul_data;
wire iresult_q_sign;
wire iresult_r_sign;
assign iresult_q_sign = iresult_mul_sign;
assign iresult_r_sign = (~subop_unsign_u1 & reg1_rdata_i[31]);
wire div_hold;
wire [`REG_BUS_WIDTH-1:0] div_reg_waddr;
wire [`DATA_BUS_WIDTH-1:0] iresult_div_rem;
wire iresult_div_rem_vld;
pa_core_exu_div u_pa_core_exu_div (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.data1_i (op1_div_data),
.data2_i (op2_div_data),
.reg_waddr_i (reg_waddr_i),
.op_div_i (op_div),
.op_rem_i (op_rem),
.q_sign_i (iresult_q_sign),
.r_sign_i (iresult_r_sign),
.hold_o (div_hold),
.reg_waddr_o (div_reg_waddr),
.data_o (iresult_div_rem),
.data_vld_o (iresult_div_rem_vld)
);
reg [`DATA_BUS_WIDTH-1:0] iresult_m_final;
always @ (*) begin
iresult_m_final = `ZERO_WORD;
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
`INST_FUNC_MUL : iresult_m_final = {32{subop_high}} & iresult_mul[63:32]
| {32{subop_low }} & iresult_mul[31: 0];
endcase
end
reg iresult_m_vld;
always @ (*) begin
iresult_m_vld = `INVALID;
case (inst_func_i[`INST_FUNC_WIDTH-1:0] & 32'h00_ffffff)
`INST_FUNC_MUL : iresult_m_vld = `VALID;
`INST_FUNC_DIV : iresult_m_vld = `VALID;
`INST_FUNC_REM : iresult_m_vld = `VALID;
endcase
end
assign csr_waddr_vld_o = (op_csrrw || op_csrrs || op_csrrc);
assign csr_wdata_o[`DATA_BUS_WIDTH-1:0] = {32{op_csrrw}} & iresult_csrw
| {32{op_csrrs}} & iresult_csrs
| {32{op_csrrc}} & iresult_csrc;
assign mem_en_o = (op_load || op_store);
assign hold_flag_o = (op_store || op_load)
|| (op_div || op_rem || div_hold);
assign jump_flag_o = (op_b && bxx_valid)
|| (op_jal || op_jalr);
assign jump_addr_o = {32{op_b && bxx_valid}} & result_pc_bxx
| {32{op_jal || op_jalr}} & result_pc_jalx;
assign reg_waddr_o[`REG_BUS_WIDTH-1:0] = iresult_div_rem_vld ? div_reg_waddr[`REG_BUS_WIDTH-1:0]
: reg_waddr_i[`REG_BUS_WIDTH-1:0];
assign reg_waddr_vld_o = iresult_div_rem_vld ? 1'b1
: reg_waddr_vld_i;
assign iresult_o[`DATA_BUS_WIDTH-1:0] = {32{inst_set_rvi & iresult_i_vld}} & iresult_i_final[`DATA_BUS_WIDTH-1:0]
| {32{inst_set_rvm & iresult_m_vld}} & iresult_m_final[`DATA_BUS_WIDTH-1:0]
| {32{iresult_div_rem_vld }} & iresult_div_rem[`DATA_BUS_WIDTH-1:0];
assign iresult_vld_o = inst_set_rvi & iresult_i_vld
| inst_set_rvm & iresult_m_vld
| iresult_div_rem_vld;
endmodule

View File

@ -0,0 +1,193 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-14 Lyons v3.0, add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_exu_div (
input wire clk_i,
input wire rst_n_i,
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
input wire [`DATA_BUS_WIDTH-1:0] data2_i,
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
input wire op_div_i,
input wire op_rem_i,
input wire q_sign_i,
input wire r_sign_i,
output wire hold_o,
output wire [`REG_BUS_WIDTH-1:0] reg_waddr_o,
output wire [31:0] data_o,
output wire data_vld_o
);
wire div_start;
assign div_start = (op_div_i || op_rem_i);
wire [31:0] data_dividend;
pa_dff_rst_0 #(32) dff_data_dividend (clk_i, rst_n_i, div_start, data1_i, data_dividend);
wire [31:0] data_divisor;
pa_dff_rst_0 #(32) dff_data_divisor (clk_i, rst_n_i, div_start, data2_i, data_divisor);
wire q_sign;
pa_dff_rst_0 #(1) dff_q_sign (clk_i, rst_n_i, div_start, q_sign_i, q_sign);
wire r_sign;
pa_dff_rst_0 #(1) dff_r_sign (clk_i, rst_n_i, div_start, r_sign_i, r_sign);
wire op;
pa_dff_rst_0 #(1) dff_op (clk_i, rst_n_i, div_start, op_div_i, op);
wire [`REG_BUS_WIDTH-1:0] reg_waddr;
pa_dff_rst_0 #(`REG_BUS_WIDTH) dff_reg_waddr (clk_i, rst_n_i, div_start, reg_waddr_i, reg_waddr);
wire [64:0] current_divisor_n; // [-y]
wire [64:0] current_divisor_p; // [ y]
assign current_divisor_n[64:0] = {1'b1, (~data_divisor[31:0] + 32'd1), 32'b0}; // [-y]
assign current_divisor_p[64:0] = {1'b0, data_divisor[31:0], 32'b0}; // [ y]
// 'divide_zero' is valid when 'data_divisor' is equal to zero
// 'divide_sel' is valid when 'data_divisor' is greater than 'data_dividend'
wire divide_zero;
wire divide_sel;
assign divide_zero = ~(|data_divisor[31:0]);
assign divide_sel = (data_divisor > data_dividend);
// division process
reg [5:0] div_cnt;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
div_cnt <= 6'd33;
end
else if (div_start) begin
if (data2_i == 32'd0) begin
div_cnt <= 6'd32;
end
else if (data2_i > data1_i) begin
div_cnt <= 6'd32;
end
else begin
div_cnt <= 6'd0;
end
end
else if (div_cnt > 6'd32) begin
div_cnt <= div_cnt;
end
else begin
div_cnt <= div_cnt + 6'd1;
end
end
wire sm_start;
wire sm_running;
wire sm_stop;
assign sm_start = (div_cnt == 6'd0);
assign sm_running = (div_cnt >= 6'd0) && (div_cnt <= 6'd32);
assign sm_stop = (div_cnt == 6'd32);
wire [64:0] rst_remainder;
wire [64:0] current_remainder;
reg [64:0] next_remainder;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
next_remainder[64:0] <= 65'b0;
end
else if (sm_start) begin
next_remainder[64:0] <= {33'b0, data_dividend[31:0]};
end
else if (sm_stop) begin
next_remainder[64:0] <= next_remainder[64:0];
end
else if (sm_running) begin
next_remainder[64:0] <= rst_remainder[64:0];
end
else begin
next_remainder[64:0] <= 65'b0;
end
end
assign current_remainder[64:0] = {next_remainder[63:0], 1'b0};
wire [64:0] rst_remainder_sub;
wire [64:0] rst_remainder_add;
assign rst_remainder_sub[64:0] = current_remainder[64:0]
+ current_divisor_n[64:0];
assign rst_remainder_add[64:0] = current_remainder[64:0]
+ current_divisor_p[64:0];
assign rst_remainder[64:1] = current_remainder[64] ? rst_remainder_add[64:1]
: rst_remainder_sub[64:1];
assign rst_remainder[0] = !rst_remainder[64];
wire [31:0] rst_qt;
wire [31:0] rst_rem;
assign rst_qt[31:0] = rst_remainder[31:0];
wire [64:0] rst_remainder_back;
assign rst_remainder_back[64:0] = rst_remainder[64:0]
+ current_divisor_p[64:0];
assign rst_rem[31:0] = rst_remainder[64] ? rst_remainder_back[63:32]
: rst_remainder[63:32];
wire [31:0] rst_qt_final_t;
wire [31:0] rst_rem_final_t;
assign rst_qt_final_t[31:0] = divide_zero ? 32'hffff_ffff
: (divide_sel ? 32'b0 : rst_qt[31:0]);
assign rst_rem_final_t[31:0] = divide_zero ? data_dividend[31:0]
: (divide_sel ? data_dividend[31:0] : rst_rem[31:0]);
wire [31:0] rst_qt_final;
wire [31:0] rst_rem_final;
assign rst_qt_final[31:0] = q_sign ? (~rst_qt_final_t[31:0] + 32'd1)
: rst_qt_final_t[31:0];
assign rst_rem_final[31:0] = r_sign ? (~rst_rem_final_t[31:0] + 32'd1)
: rst_rem_final_t[31:0];
assign hold_o = sm_running && !sm_stop;
assign reg_waddr_o[`REG_BUS_WIDTH-1:0] = {5{sm_stop}} & reg_waddr[`REG_BUS_WIDTH-1:0];
assign data_o[31:0] = {32{sm_stop}} & {op ? rst_qt_final[31:0] : rst_rem_final[31:0]};
assign data_vld_o = sm_stop;
endmodule

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-13 Lyons v3.0, add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_exu_mul (
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
input wire [`DATA_BUS_WIDTH-1:0] data2_i,
input wire sign_i,
output wire [63:0] data_o
);
wire [47:0] iresult_final_high;
wire [47:0] iresult_final_low;
// you should using multi ip here
assign iresult_final_high[47:0] = data1_i[31:0] * {16'b0, data2_i[31:16]};
assign iresult_final_low [47:0] = data1_i[31:0] * {16'b0, data2_i[15: 0]};
wire [63:0] iresult_final;
assign iresult_final[63:0] = {iresult_final_high[47:0], 16'b0}
+ {16'b0, iresult_final_low[47:0]};
assign data_o[63:0] = sign_i ? (~iresult_final[63:0] + 64'b1)
: ( iresult_final[63:0]);
endmodule

View File

@ -0,0 +1,411 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-13 Lyons v3.0, add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_idu (
input wire [`DATA_BUS_WIDTH-1:0] inst_data_i,
output wire [`INST_SET_WIDTH-1:0] inst_set_o,
output wire [`INST_TYPE_WIDTH-1:0] inst_type_o,
output wire [`INST_FUNC_WIDTH-1:0] inst_func_o,
output wire [`REG_BUS_WIDTH-1:0] reg1_raddr_o,
output wire [`REG_BUS_WIDTH-1:0] reg2_raddr_o,
output wire [`REG_BUS_WIDTH-1:0] reg_waddr_o,
output wire reg_waddr_vld_o,
output wire [`DATA_BUS_WIDTH-1:0] uimm_o,
output wire [`CSR_BUS_WIDTH-1:0] csr_o
);
wire [4:0] inst_rs3;
wire [6:0] inst_func7;
wire [4:0] inst_rs2;
wire [4:0] inst_rs1;
wire [2:0] inst_rm;
wire [2:0] inst_func3;
wire [4:0] inst_rd;
wire [6:0] inst_opcode;
assign inst_rs3[4:0] = inst_data_i[31:27];
assign inst_func7[6:0] = inst_data_i[31:25];
assign inst_rs2[4:0] = inst_data_i[24:20];
assign inst_rs1[4:0] = inst_data_i[19:15];
assign inst_rm[2:0] = inst_data_i[14:12];
assign inst_func3[2:0] = inst_data_i[14:12];
assign inst_rd[4:0] = inst_data_i[11: 7];
assign inst_opcode[6:0] = inst_data_i[ 6: 0];
wire [4:0] inst_uimm5;
assign inst_uimm5[4:0] = inst_data_i[19:15];
wire [11:0] inst_uimm12_b_type;
wire [11:0] inst_uimm12_i_type;
wire [11:0] inst_uimm12_s_type;
assign inst_uimm12_b_type[11:0] = {inst_data_i[31],
inst_data_i[7],
inst_data_i[30:25],
inst_data_i[11: 8]};
assign inst_uimm12_i_type[11:0] = {inst_data_i[31:20]};
assign inst_uimm12_s_type[11:0] = {inst_data_i[31:25],
inst_data_i[11: 7]};
wire [19:0] inst_uimm20_j_type;
wire [19:0] inst_uimm20_u_type;
assign inst_uimm20_j_type[19:0] = {inst_data_i[31],
inst_data_i[19:12],
inst_data_i[20],
inst_data_i[30:21]};
assign inst_uimm20_u_type[19:0] = {inst_data_i[31:12]};
wire inst_rs2_all0;
wire inst_rs1_all0;
wire inst_func3_all0;
wire inst_rd_all0;
assign inst_rs2_all0 = ~(|inst_rs2[4:0]);
assign inst_rs1_all0 = ~(|inst_rs1[4:0]);
assign inst_func3_all0 = ~(|inst_func3[2:0]);
assign inst_rd_all0 = ~(|inst_rd[4:0]);
wire inst_is_ecall;
wire inst_is_ebreak;
wire inst_is_mret;
wire inst_is_wfi;
wire inst_is_csrrx;
wire inst_is_csrri;
assign inst_is_ecall = (inst_data_i[31:20] == 12'h000) && inst_rs1_all0 && inst_func3_all0 && inst_rd_all0;
assign inst_is_ebreak = (inst_data_i[31:20] == 12'h001) && inst_rs1_all0 && inst_func3_all0 && inst_rd_all0;
assign inst_is_mret = (inst_data_i[31:20] == 12'h302) && inst_rs1_all0 && inst_func3_all0 && inst_rd_all0;
assign inst_is_wfi = (inst_data_i[31:20] == 12'h105) && inst_rs1_all0 && inst_func3_all0;
assign inst_is_csrrx = (~inst_func3[2]) && (~inst_func3_all0);
assign inst_is_csrri = ( inst_func3[2]) && (~inst_func3_all0);
// analyse, get 'inst_set' and 'inst_type'
// modify here when add new inst set or inst
reg [`INST_SET_WIDTH-1:0] inst_set;
reg [`INST_TYPE_WIDTH-1:0] inst_type;
always @ (*) begin
case (inst_opcode[6:0])
7'b0000011 , // lb/lh/lw/lbu/lhu
7'b1100111 , // jalr
7'b0010011 : begin // addi/slli/slti/sltiu/xori/srli/srai/ori/andi
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_I;
end
7'b0010111 , // auipc
7'b0110111 : begin // lui
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_U;
end
7'b0100011 : begin // sb/sh/sw
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_S;
end
7'b0110011 : begin // add/sub/sll/slt/sltu/xor/srl/sra/or/and
// mul/mulh/mulhsu/mulhu/div/divu/rem/remu
inst_set[`INST_SET_WIDTH-1:0] = inst_func7[0] ? `INST_SET_RV32M
: `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_R;
end
7'b1100011 : begin // beq/bne/blt/bge/bltu/bgeu
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_B;
end
7'b1101111 : begin // jal
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_J;
end
7'b1110011 : begin // ecall/ebreak/mret/wfi/csrrw/csrrs/csrrc/csrrwi/csrrsi/csrrci
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_RV32I;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_CSR;
end
default : begin
inst_set[`INST_SET_WIDTH-1:0] = `INST_SET_NULL;
inst_type[`INST_TYPE_WIDTH-1:0] = `INST_TYPE_NULL;
end
endcase
end
reg [`DATA_BUS_WIDTH-1:0] uimm;
reg [`CSR_BUS_WIDTH-1:0] csr;
always @ (*) begin
case (inst_type[6:0])
`INST_TYPE_R : begin
uimm = `ZERO_WORD;
csr = `CSR_NULL;
end
`INST_TYPE_I : begin
uimm = {20'b0, inst_uimm12_i_type[11:0]};
csr = `CSR_NULL;
end
`INST_TYPE_S : begin
uimm = {20'b0, inst_uimm12_s_type[11:0]};
csr = `CSR_NULL;
end
`INST_TYPE_B : begin
uimm = {20'b0, inst_uimm12_b_type[11:0]};
csr = `CSR_NULL;
end
`INST_TYPE_U : begin
uimm = {12'b0, inst_uimm20_u_type[19:0]};
csr = `CSR_NULL;
end
`INST_TYPE_J : begin
uimm = {12'b0, inst_uimm20_j_type[19:0]};
csr = `CSR_NULL;
end
`INST_TYPE_CSR : begin
uimm = inst_is_csrri ? {27'b0, inst_uimm5[4:0]} : `ZERO_WORD;
csr = {inst_func7[6:0], inst_rs2[4:0]};
end
default : begin
uimm = `ZERO_WORD;
csr = `CSR_NULL;
end
endcase
end
// analyse, get 'inst_set' and 'inst_func'
// modify here when add new inst set or inst
reg [`INST_FUNC_WIDTH-1:0] inst_func;
always @ (*) begin
inst_func = `INST_FUNC_NULL;
case (inst_opcode[6:0])
7'b0000011 : begin
case (inst_func3[2:0])
`INST_LB : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_BYTE;
`INST_LH : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_HALF;
`INST_LW : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM;
`INST_LBU : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_BYTE | `INST_FUNC_SUFFIX_UNSIGN;
`INST_LHU : inst_func = `INST_FUNC_LOAD | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_HALF | `INST_FUNC_SUFFIX_UNSIGN;
endcase
end
7'b0010011 : begin
case (inst_func3[2:0])
`INST_ADD : inst_func = `INST_FUNC_ADD | `INST_FUNC_SUFFIX_IMM;
`INST_SLL : inst_func = `INST_FUNC_SLL | `INST_FUNC_SUFFIX_IMM;
`INST_SLT : inst_func = `INST_FUNC_SLT | `INST_FUNC_SUFFIX_IMM;
`INST_SLTU : inst_func = `INST_FUNC_SLT | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_UNSIGN;
`INST_XOR : inst_func = `INST_FUNC_XOR | `INST_FUNC_SUFFIX_IMM;
`INST_SRL : inst_func = (inst_func7[5] ? `INST_FUNC_SRA : `INST_FUNC_SRL) | `INST_FUNC_SUFFIX_IMM;
`INST_OR : inst_func = `INST_FUNC_OR | `INST_FUNC_SUFFIX_IMM;
`INST_AND : inst_func = `INST_FUNC_AND | `INST_FUNC_SUFFIX_IMM;
endcase
end
7'b0010111 : begin
inst_func = `INST_FUNC_AUIPC;
end
7'b0100011 : begin
case (inst_func3[2:0])
`INST_SB : inst_func = `INST_FUNC_STORE | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_BYTE;
`INST_SH : inst_func = `INST_FUNC_STORE | `INST_FUNC_SUFFIX_IMM | `INST_FUNC_SUFFIX_HALF;
`INST_SW : inst_func = `INST_FUNC_STORE | `INST_FUNC_SUFFIX_IMM;
endcase
end
7'b0110011 : begin
if (inst_func7[0]) begin
case (inst_func3[2:0])
`INST_MUL : inst_func = `INST_FUNC_MUL;
`INST_MULH : inst_func = `INST_FUNC_MUL | `INST_FUNC_SUFFIX_HIGH;
`INST_MULHSU : inst_func = `INST_FUNC_MUL | `INST_FUNC_SUFFIX_U2 | `INST_FUNC_SUFFIX_HIGH;
`INST_MULHU : inst_func = `INST_FUNC_MUL | `INST_FUNC_SUFFIX_U1 | `INST_FUNC_SUFFIX_U2 | `INST_FUNC_SUFFIX_HIGH;
`INST_DIV : inst_func = `INST_FUNC_DIV;
`INST_DIVU : inst_func = `INST_FUNC_DIV | `INST_FUNC_SUFFIX_U1 | `INST_FUNC_SUFFIX_U2;
`INST_REM : inst_func = `INST_FUNC_REM;
`INST_REMU : inst_func = `INST_FUNC_REM | `INST_FUNC_SUFFIX_U1 | `INST_FUNC_SUFFIX_U2;
endcase
end
else begin
case (inst_func3[2:0])
`INST_ADD : inst_func = (inst_func7[5] ? `INST_FUNC_SUB : `INST_FUNC_ADD);
`INST_SLL : inst_func = `INST_FUNC_SLL;
`INST_SLT : inst_func = `INST_FUNC_SLT;
`INST_SLTU : inst_func = `INST_FUNC_SLT | `INST_FUNC_SUFFIX_UNSIGN;
`INST_XOR : inst_func = `INST_FUNC_XOR;
`INST_SRL : inst_func = (inst_func7[5] ? `INST_FUNC_SRA : `INST_FUNC_SRL);
`INST_OR : inst_func = `INST_FUNC_OR;
`INST_AND : inst_func = `INST_FUNC_AND;
endcase
end
end
7'b0110111 : begin
inst_func = `INST_FUNC_LUI | `INST_FUNC_SUFFIX_IMM;
end
7'b1100011 : begin
case (inst_func3[2:0])
`INST_BEQ : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_EQ;
`INST_BNE : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_NE;
`INST_BLT : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_LT;
`INST_BGE : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_GT | `INST_FUNC_SUFFIX_EQ;
`INST_BLTU : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_LT | `INST_FUNC_SUFFIX_UNSIGN;
`INST_BGEU : inst_func = `INST_FUNC_B | `INST_FUNC_SUFFIX_GT | `INST_FUNC_SUFFIX_EQ | `INST_FUNC_SUFFIX_UNSIGN;
endcase
end
7'b1101111 : begin
inst_func = `INST_FUNC_JAL;
end
7'b1100111 : begin
inst_func = `INST_FUNC_JALR;
end
7'b1110011 : begin
case (inst_func3[2:0])
`INST_ECALL : begin
case ({inst_is_ecall, inst_is_ebreak, inst_is_mret, inst_is_wfi})
4'b1000 : inst_func = `INST_FUNC_ECALL;
4'b0100 : inst_func = `INST_FUNC_EBREAK;
4'b0010 : inst_func = `INST_FUNC_MRET;
4'b0001 : inst_func = `INST_FUNC_WFI;
default : inst_func = `INST_FUNC_NULL;
endcase
end
`INST_CSRRW : inst_func = `INST_FUNC_CSRRW;
`INST_CSRRS : inst_func = `INST_FUNC_CSRRS;
`INST_CSRRC : inst_func = `INST_FUNC_CSRRC;
`INST_CSRRWI : inst_func = `INST_FUNC_CSRRW | `INST_FUNC_SUFFIX_IMM;
`INST_CSRRSI : inst_func = `INST_FUNC_CSRRS | `INST_FUNC_SUFFIX_IMM;
`INST_CSRRCI : inst_func = `INST_FUNC_CSRRC | `INST_FUNC_SUFFIX_IMM;
endcase
end
endcase
end
reg reg_raddr1_vld;
reg reg_raddr2_vld;
reg reg_waddr_vld;
reg imm_vld;
reg csr_vld;
always @ (*) begin
case (inst_type[6:0])
`INST_TYPE_R : begin
reg_raddr1_vld = `VALID;
reg_raddr2_vld = `VALID;
case (inst_set[`INST_SET_WIDTH-1:0])
`INST_SET_RV32I ,
`INST_SET_RV32M : begin
reg_waddr_vld = `VALID;
end
`INST_SET_RV32FD : begin
reg_waddr_vld = `INVALID;
end
default : begin
reg_waddr_vld = `INVALID;
end
endcase
imm_vld = `INVALID;
csr_vld = `INVALID;
end
`INST_TYPE_I : begin
reg_raddr1_vld = `VALID;
reg_raddr2_vld = `INVALID;
reg_waddr_vld = `VALID;
imm_vld = `VALID;
csr_vld = `INVALID;
end
`INST_TYPE_S : begin
reg_raddr1_vld = `VALID;
reg_raddr2_vld = `VALID;
reg_waddr_vld = `INVALID;
imm_vld = `VALID;
csr_vld = `INVALID;
end
`INST_TYPE_B : begin
reg_raddr1_vld = `VALID;
reg_raddr2_vld = `VALID;
reg_waddr_vld = `INVALID;
imm_vld = `VALID;
csr_vld = `INVALID;
end
`INST_TYPE_U : begin
reg_raddr1_vld = `INVALID;
reg_raddr2_vld = `INVALID;
reg_waddr_vld = `VALID;
imm_vld = `VALID;
csr_vld = `INVALID;
end
`INST_TYPE_J : begin
reg_raddr1_vld = `INVALID;
reg_raddr2_vld = `INVALID;
reg_waddr_vld = `VALID;
imm_vld = `VALID;
csr_vld = `INVALID;
end
`INST_TYPE_CSR : begin
reg_raddr1_vld = inst_is_csrrx ? `VALID : `INVALID;
reg_raddr2_vld = `INVALID;
reg_waddr_vld = `VALID;
imm_vld = inst_is_csrri ? `VALID : `INVALID;
csr_vld = `VALID;
end
default : begin
reg_raddr1_vld = `INVALID;
reg_raddr2_vld = `INVALID;
reg_waddr_vld = `INVALID;
imm_vld = `INVALID;
csr_vld = `INVALID;
end
endcase
end
assign inst_set_o[`INST_SET_WIDTH-1:0] = inst_set[`INST_SET_WIDTH-1:0];
assign inst_type_o[`INST_TYPE_WIDTH-1:0] = inst_type[`INST_TYPE_WIDTH-1:0];
assign inst_func_o[`INST_FUNC_WIDTH-1:0] = inst_func[`INST_FUNC_WIDTH-1:0];
// data keep zero while field is invalid
assign reg1_raddr_o[`REG_BUS_WIDTH-1:0] = {{`REG_BUS_WIDTH}{reg_raddr1_vld}} & inst_rs1[`REG_BUS_WIDTH-1:0];
assign reg2_raddr_o[`REG_BUS_WIDTH-1:0] = {{`REG_BUS_WIDTH}{reg_raddr2_vld}} & inst_rs2[`REG_BUS_WIDTH-1:0];
assign reg_waddr_o[`REG_BUS_WIDTH-1:0] = {{`REG_BUS_WIDTH}{reg_waddr_vld}} & inst_rd[`REG_BUS_WIDTH-1:0];
assign reg_waddr_vld_o = reg_waddr_vld;
assign uimm_o[`DATA_BUS_WIDTH-1:0] = {{`DATA_BUS_WIDTH}{imm_vld}} & uimm[`DATA_BUS_WIDTH-1:0];
assign csr_o[`CSR_BUS_WIDTH-1:0] = {{`CSR_BUS_WIDTH }{csr_vld}} & csr[`CSR_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-13 Lyons v3.0, add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_mau (
input wire [4:0] inst_func_i, // indicate instruction func, [31,29:28,op_load,op_store]
input wire [1:0] mem_addr_i,
input wire [`DATA_BUS_WIDTH-1:0] mem_data_i,
input wire mem_data_vld_i,
output wire [`DATA_BUS_WIDTH-1:0] mem_data_o,
output wire mem_data_vld_o,
input wire [`DATA_BUS_WIDTH-1:0] rbm_data_i,
output wire [`DATA_BUS_WIDTH-1:0] rbm_data_o,
output wire [2:0] rbm_size_o
);
wire subop_sign;
wire subop_byte;
wire subop_half;
wire subop_word;
assign subop_sign = ~inst_func_i[4]; // to inst_func_i[31]
assign subop_byte = (inst_func_i[3:2] == 2'b01); // to inst_func_i[29:28]
assign subop_half = (inst_func_i[3:2] == 2'b10); // to inst_func_i[29:28]
assign subop_word = (inst_func_i[3:2] == 2'b00); // to inst_func_i[29:28]
wire op_load;
wire op_store;
assign op_load = inst_func_i[1]; // to inst_func_i[14]
assign op_store = inst_func_i[0]; // to inst_func_i[13]
wire [`DATA_BUS_WIDTH-1:0] mem_data;
// 'mem_data' is equal to zero when it is Non-memory-access inst
assign mem_data = {32{op_load }} & rbm_data_i
| {32{op_store}} & mem_data_i;
// memory byte access: lb/sb
wire [`DATA_BUS_WIDTH-1:0] mem_data_b0;
wire [`DATA_BUS_WIDTH-1:0] mem_data_b1;
wire [`DATA_BUS_WIDTH-1:0] mem_data_b2;
wire [`DATA_BUS_WIDTH-1:0] mem_data_b3;
wire [`DATA_BUS_WIDTH-1:0] mem_data_b;
assign mem_data_b0 = op_load ? {24'b0 | {24{subop_sign && mem_data[ 7]}}, mem_data[ 7: 0]}
: {mem_data[31:0]};
assign mem_data_b1 = op_load ? {24'b0 | {24{subop_sign && mem_data[15]}}, mem_data[15: 8]}
: {mem_data[23:0], 8'b0 };
assign mem_data_b2 = op_load ? {24'b0 | {24{subop_sign && mem_data[23]}}, mem_data[23:16]}
: {mem_data[15:0], 16'b0};
assign mem_data_b3 = op_load ? {24'b0 | {24{subop_sign && mem_data[31]}}, mem_data[31:24]}
: {mem_data[ 7:0], 24'b0};
assign mem_data_b = {32{mem_addr_i[1:0] == 2'b00}} & mem_data_b0
| {32{mem_addr_i[1:0] == 2'b01}} & mem_data_b1
| {32{mem_addr_i[1:0] == 2'b10}} & mem_data_b2
| {32{mem_addr_i[1:0] == 2'b11}} & mem_data_b3;
// memory half-word access: lh/sh
wire [`DATA_BUS_WIDTH-1:0] mem_data_h0;
wire [`DATA_BUS_WIDTH-1:0] mem_data_h1;
wire [`DATA_BUS_WIDTH-1:0] mem_data_h;
assign mem_data_h0 = op_load ? {16'b0 | {16{subop_sign && mem_data[15]}}, mem_data[15: 0]}
: {mem_data[31:0]};
assign mem_data_h1 = op_load ? {16'b0 | {16{subop_sign && mem_data[31]}}, mem_data[31:16]}
: {mem_data[15:0], 16'b0};
assign mem_data_h = {32{mem_addr_i[1] == 1'b0}} & mem_data_h0
| {32{mem_addr_i[1] == 1'b1}} & mem_data_h1;
// memory word access: lw/sw
wire [`DATA_BUS_WIDTH-1:0] mem_data_w;
assign mem_data_w = {mem_data[31:0]};
// 'mem_wdata' is equal to zero when it is Non-load inst
wire [`DATA_BUS_WIDTH-1:0] mem_wdata/* synthesis syn_keep=1 */;
assign mem_wdata = {32{subop_byte}} & mem_data_b
| {32{subop_half}} & mem_data_h
| {32{subop_word}} & mem_data_w;
// to exec unit, process data
assign mem_data_o[`DATA_BUS_WIDTH-1:0] = mem_wdata[`DATA_BUS_WIDTH-1:0];
assign mem_data_vld_o = op_load;
// to bus, store data
assign rbm_data_o[`DATA_BUS_WIDTH-1:0] = mem_wdata[`DATA_BUS_WIDTH-1:0];
assign rbm_size_o = {subop_word, subop_half, subop_byte};
endmodule

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-13 Lyons v3.0, add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_pcgen (
input wire clk_i,
input wire rst_n_i,
input wire reset_flag_i,
input wire hold_flag_i,
input wire jump_flag_i,
input wire [`DATA_BUS_WIDTH-1:0] jump_addr_i,
output wire [`DATA_BUS_WIDTH-1:0] pc_o
);
reg [`DATA_BUS_WIDTH-1:0] _pc;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
// hardware power-on reset
_pc[`DATA_BUS_WIDTH-1:0] <= `RESET_PC_ADDR;
end
else if (reset_flag_i) begin
// software reset
_pc[`DATA_BUS_WIDTH-1:0] <= `RESET_PC_ADDR;
end
else if (jump_flag_i) begin
// jump
_pc[`DATA_BUS_WIDTH-1:0] <= jump_addr_i[`DATA_BUS_WIDTH-1:0];
end
else if (hold_flag_i) begin
// cpu stall & hold
_pc[`DATA_BUS_WIDTH-1:0] <= _pc[`DATA_BUS_WIDTH-1:0];
end
else begin
// only support 32-bits instruction
_pc[`DATA_BUS_WIDTH-1:0] <= _pc[`DATA_BUS_WIDTH-1:0] + 32'h4;
end
end
assign pc_o[`DATA_BUS_WIDTH-1:0] = _pc[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_rtu (
input wire clk_i,
input wire rst_n_i,
input wire [`REG_BUS_WIDTH-1:0] reg1_raddr_i,
input wire [`REG_BUS_WIDTH-1:0] reg2_raddr_i,
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
input wire reg_waddr_vld_i,
input wire [`DATA_BUS_WIDTH-1:0] reg_wdata_i,
output wire [`DATA_BUS_WIDTH-1:0] reg1_rdata_o,
output wire [`DATA_BUS_WIDTH-1:0] reg2_rdata_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_mepc_o,
output wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_o,
input wire [`CSR_BUS_WIDTH-1:0] csr_raddr_i,
input wire [`CSR_BUS_WIDTH-1:0] csr_waddr_i,
input wire csr_waddr_vld_i,
input wire [`DATA_BUS_WIDTH-1:0] csr_wdata_i,
output wire [`DATA_BUS_WIDTH-1:0] csr_rdata_o
);
pa_core_csr u_pa_core_csr (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.csr_mtvec_o (csr_mtvec_o),
.csr_mepc_o (csr_mepc_o),
.csr_mstatus_o (csr_mstatus_o),
.csr_raddr_i (csr_raddr_i),
.csr_waddr_i (csr_waddr_i),
.csr_waddr_vld_i (csr_waddr_vld_i),
.csr_wdata_i (csr_wdata_i),
.csr_rdata_o (csr_rdata_o)
);
pa_core_xreg u_pa_core_xreg (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.reg1_raddr_i (reg1_raddr_i),
.reg2_raddr_i (reg2_raddr_i),
.reg_waddr_i (reg_waddr_i),
.reg_waddr_vld_i (reg_waddr_vld_i),
.reg_wdata_i (reg_wdata_i),
.reg1_rdata_o (reg1_rdata_o),
.reg2_rdata_o (reg2_rdata_o)
);
endmodule

View File

@ -0,0 +1,417 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2023-06-10 Lyons v3.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_top (
input wire clk_i,
input wire rst_n_i,
input wire irq_i,
output wire [`ADDR_BUS_WIDTH-1:0] ibus_addr_o,
input wire [`DATA_BUS_WIDTH-1:0] ibus_data_i,
output wire [`ADDR_BUS_WIDTH-1:0] dbus_addr_o,
output dbus_rd_o,
output dbus_we_o,
output wire [2:0] dbus_size_o,
output wire [`DATA_BUS_WIDTH-1:0] dbus_data_o,
input wire [`DATA_BUS_WIDTH-1:0] dbus_data_i
);
wire exu_hold_flag;
wire int_hold_flag;
wire hold_flag;
wire jump_flag;
wire [`ADDR_BUS_WIDTH-1:0] jump_addr;
wire idu_flush_flag;
wire exu_flush_flag;
wire hold_flag_1r;
pa_dff_rst_0 #(1) dff_hold_flag_1r (clk_i, rst_n_i, `VALID, hold_flag, hold_flag_1r);
wire jump_flag_1r;
pa_dff_rst_0 #(1) dff_jump_flag_1r (clk_i, rst_n_i, `VALID, jump_flag, jump_flag_1r);
// inst address generated from pcgen module
// inst data fetched after one clock
wire [`ADDR_BUS_WIDTH-1:0] inst_addr;
wire [`DATA_BUS_WIDTH-1:0] inst_data;
pa_core_pcgen u_pa_core_pcgen (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.reset_flag_i (`INVALID),
.hold_flag_i (hold_flag),
.jump_flag_i (jump_flag),
.jump_addr_i (jump_addr),
.pc_o (inst_addr)
);
// "ifu_inst_addr" work under IF state
wire [`ADDR_BUS_WIDTH-1:0] ifu_inst_addr;
assign ifu_inst_addr[`ADDR_BUS_WIDTH-1:0] = inst_addr[`ADDR_BUS_WIDTH-1:0];
// inst data fetched from tcm module by bus
assign ibus_addr_o[`ADDR_BUS_WIDTH-1:0] = ifu_inst_addr[`ADDR_BUS_WIDTH-1:0];
assign inst_data[`DATA_BUS_WIDTH-1:0] = ibus_data_i[`DATA_BUS_WIDTH-1:0];
// "idu_inst_data" work under ID state
wire [`DATA_BUS_WIDTH-1:0] idu_inst_data;
wire [`DATA_BUS_WIDTH-1:0] inst_data_1r;
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_inst_data_1r (clk_i, rst_n_i, idu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, idu_inst_data, inst_data_1r);
assign idu_inst_data[`DATA_BUS_WIDTH-1:0] = hold_flag_1r ? inst_data_1r[`DATA_BUS_WIDTH-1:0]
: inst_data[`DATA_BUS_WIDTH-1:0];
wire [`INST_SET_WIDTH-1:0] inst_set;
wire [`INST_TYPE_WIDTH-1:0] inst_type;
wire [`INST_FUNC_WIDTH-1:0] inst_func;
wire [`REG_BUS_WIDTH-1:0] reg1_raddr;
wire [`REG_BUS_WIDTH-1:0] reg2_raddr;
wire [`DATA_BUS_WIDTH-1:0] reg1_rdata;
wire [`DATA_BUS_WIDTH-1:0] reg2_rdata;
wire [`REG_BUS_WIDTH-1:0] reg_waddr;
wire reg_waddr_vld;
wire [`DATA_BUS_WIDTH-1:0] uimm_data;
wire [`CSR_BUS_WIDTH-1:0] csr_addr;
// ifu module only include comb logic, no timing logic
pa_core_idu u_pa_core_idu (
.inst_data_i (idu_inst_data),
.inst_set_o (inst_set),
.inst_type_o (inst_type),
.inst_func_o (inst_func),
.reg1_raddr_o (reg1_raddr),
.reg2_raddr_o (reg2_raddr),
.reg_waddr_o (reg_waddr),
.reg_waddr_vld_o (reg_waddr_vld),
.uimm_o (uimm_data),
.csr_o (csr_addr)
);
wire [`INST_SET_WIDTH-1:0] exu_inst_set;
pa_dff_en_2 #(`INST_SET_WIDTH) dff_exu_inst_set (clk_i, rst_n_i, exu_flush_flag, {`INST_SET_WIDTH{1'b0}}, inst_set, exu_inst_set);
wire [`INST_FUNC_WIDTH-1:0] exu_inst_func;
pa_dff_en_2 #(`INST_FUNC_WIDTH) dff_exu_inst_func (clk_i, rst_n_i, exu_flush_flag, {`INST_FUNC_WIDTH{1'b0}}, inst_func, exu_inst_func);
wire [`DATA_BUS_WIDTH-1:0] exu_reg1_rdata;
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_exu_reg1_rdata (clk_i, rst_n_i, exu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, reg1_rdata, exu_reg1_rdata);
wire [`DATA_BUS_WIDTH-1:0] exu_reg2_rdata;
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_exu_reg2_rdata (clk_i, rst_n_i, exu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, reg2_rdata, exu_reg2_rdata);
wire [`REG_BUS_WIDTH-1:0] exu_reg_waddr;
pa_dff_en_2 #(`REG_BUS_WIDTH) dff_exu_reg_waddr (clk_i, rst_n_i, exu_flush_flag, {`REG_BUS_WIDTH{1'b0}}, reg_waddr, exu_reg_waddr);
wire exu_reg_waddr_vld;
pa_dff_en_2 #(1) dff_exu_reg_waddr_vld (clk_i, rst_n_i, exu_flush_flag, 1'b0, reg_waddr_vld, exu_reg_waddr_vld);
wire [`DATA_BUS_WIDTH-1:0] exu_uimm_data;
pa_dff_en_2 #(`DATA_BUS_WIDTH) dff_exu_uimm_data (clk_i, rst_n_i, exu_flush_flag, {`DATA_BUS_WIDTH{1'b0}}, uimm_data, exu_uimm_data);
wire [`CSR_BUS_WIDTH-1:0] exu_csr_addr;
pa_dff_en_2 #(`CSR_BUS_WIDTH) dff_exu_csr_addr (clk_i, rst_n_i, exu_flush_flag, {`CSR_BUS_WIDTH{1'b0}}, csr_addr, exu_csr_addr);
// exu module generate "exu_hold_flag" signal if extend EX state
wire [`DATA_BUS_WIDTH-1:0] exu_csr_rdata;
wire exu_csr_waddr_vld;
wire [`DATA_BUS_WIDTH-1:0] exu_csr_wdata;
wire mem_en_flag;
wire exu_jump_flag;
wire [`ADDR_BUS_WIDTH-1:0] exu_jump_addr;
wire [`REG_BUS_WIDTH-1:0] reg_waddr_wb;
wire reg_waddr_wb_vld;
wire [`DATA_BUS_WIDTH-1:0] iresult;
wire iresult_vld;
pa_core_exu u_pa_core_exu (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.inst_set_i (exu_inst_set[1:0]),
.inst_func_i (exu_inst_func),
.pc_i (ifu_inst_addr),
.reg1_rdata_i (exu_reg1_rdata),
.reg2_rdata_i (exu_reg2_rdata),
.uimm_i (exu_uimm_data[19:0]),
.reg_waddr_i (exu_reg_waddr),
.reg_waddr_vld_i (exu_reg_waddr_vld),
.csr_rdata_i (exu_csr_rdata),
.csr_waddr_vld_o (exu_csr_waddr_vld),
.csr_wdata_o (exu_csr_wdata),
.mem_en_o (mem_en_flag),
.hold_flag_o (exu_hold_flag),
.jump_flag_o (exu_jump_flag),
.jump_addr_o (exu_jump_addr),
.reg_waddr_o (reg_waddr_wb),
.reg_waddr_vld_o (reg_waddr_wb_vld),
.iresult_o (iresult),
.iresult_vld_o (iresult_vld)
);
// clint module generate "int_hold_flag" signal if interrupt valid
wire [`DATA_BUS_WIDTH-1:0] csr_mtvec_data;
wire [`DATA_BUS_WIDTH-1:0] csr_mepc_data;
wire [`DATA_BUS_WIDTH-1:0] csr_mstatus_data;
wire [`CSR_BUS_WIDTH-1:0] int_csr_waddr;
wire int_csr_waddr_vld;
wire [`DATA_BUS_WIDTH-1:0] int_csr_wdata;
wire int_jump_flag;
wire [`ADDR_BUS_WIDTH-1:0] int_jump_addr;
pa_core_clint u_pa_core_clint (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.inst_set_i (exu_inst_set[0]),
.inst_func_i (exu_inst_func[6:4]),
.pc_i (ifu_inst_addr),
.inst_i (idu_inst_data),
.csr_mtvec_i (csr_mtvec_data),
.csr_mepc_i (csr_mepc_data),
.csr_mstatus_i (csr_mstatus_data),
.irq_i (irq_i),
.jump_flag_i (exu_jump_flag),
.hold_flag_i (exu_hold_flag),
.csr_waddr_o (int_csr_waddr),
.csr_waddr_vld_o (int_csr_waddr_vld),
.csr_wdata_o (int_csr_wdata),
.hold_flag_o (int_hold_flag),
.jump_flag_o (int_jump_flag),
.jump_addr_o (int_jump_addr)
);
assign hold_flag = exu_hold_flag
|| int_hold_flag;
assign jump_flag = exu_jump_flag
|| int_jump_flag;
assign jump_addr = exu_jump_flag ? exu_jump_addr
: int_jump_addr;
assign idu_flush_flag = (jump_flag)
|| (int_hold_flag);
assign exu_flush_flag = (jump_flag || jump_flag_1r)
|| (hold_flag);
wire [`CSR_BUS_WIDTH-1:0] csr_waddr;
wire csr_waddr_vld;
wire [`DATA_BUS_WIDTH-1:0] csr_wdata;
assign csr_waddr[`CSR_BUS_WIDTH-1:0] = exu_csr_addr[`CSR_BUS_WIDTH-1:0]
| int_csr_waddr[`CSR_BUS_WIDTH-1:0];
assign csr_waddr_vld = exu_csr_waddr_vld
| int_csr_waddr_vld;
assign csr_wdata[`DATA_BUS_WIDTH-1:0] = exu_csr_wdata[`DATA_BUS_WIDTH-1:0]
| int_csr_wdata[`DATA_BUS_WIDTH-1:0];
// mem store generate address in EX state, write under next clock
// mem load generate address in EX state, return data after next clock
wire mem_en_flag_1r;
pa_dff_rst_0 #(1) dff_mem_en_flag_1r (clk_i, rst_n_i, `VALID, mem_en_flag, mem_en_flag_1r);
wire [`ADDR_BUS_WIDTH-1:0] mem_addr;
wire [`DATA_BUS_WIDTH-1:0] mem_data;
wire [2:0] mem_size;
wire [`DATA_BUS_WIDTH-1:0] mem_wdata;
wire mem_wdata_vld;
wire [`DATA_BUS_WIDTH-1:0] mem_rdata;
wire mem_rdata_vld;
wire [`ADDR_BUS_WIDTH-1:0] mem_addr_1r;
pa_dff_rst_0 #(`ADDR_BUS_WIDTH) dff_mem_addr_1r (clk_i, rst_n_i, `VALID, mem_addr, mem_addr_1r);
assign mem_addr[`ADDR_BUS_WIDTH-1:0] = {{`ADDR_BUS_WIDTH}{mem_en_flag }} & iresult[`DATA_BUS_WIDTH-1:0]
| {{`ADDR_BUS_WIDTH}{mem_en_flag_1r}} & mem_addr_1r[`ADDR_BUS_WIDTH-1:0];
assign mem_wdata[`DATA_BUS_WIDTH-1:0] = {{`DATA_BUS_WIDTH}{mem_en_flag }} & exu_reg2_rdata[`DATA_BUS_WIDTH-1:0];
assign mem_wdata_vld = mem_en_flag;
wire subop_sign_1r;
pa_dff_rst_0 #(1) dff_subop_sign_1r (clk_i, rst_n_i, `VALID, exu_inst_func[31], subop_sign_1r);
wire [1:0] subop_size_1r;
pa_dff_rst_0 #(2) dff_subop_size_1r (clk_i, rst_n_i, `VALID, exu_inst_func[29:28], subop_size_1r);
wire op_load_1r;
pa_dff_rst_0 #(1) dff_op_load_1r (clk_i, rst_n_i, `VALID, exu_inst_func[14], op_load_1r);
wire subop_sign;
wire [1:0] subop_size;
wire op_load;
wire op_store;
assign subop_sign = exu_inst_func[31] || subop_sign_1r;
assign subop_size[1:0] = exu_inst_func[29:28] | subop_size_1r[1:0];
assign op_load = exu_inst_func[14] || op_load_1r;
assign op_store = exu_inst_func[13];
wire [4:0] mau_inst_func;
assign mau_inst_func[4:0] = {subop_sign, subop_size[1:0], op_load, op_store};
pa_core_mau u_pa_core_mau (
.inst_func_i (mau_inst_func),
.mem_addr_i (mem_addr[1:0]),
.mem_data_i (mem_wdata),
.mem_data_vld_i (mem_wdata_vld),
.mem_data_o (mem_rdata),
.mem_data_vld_o (mem_rdata_vld),
.rbm_data_i (dbus_data_i),
.rbm_data_o (mem_data),
.rbm_size_o (mem_size)
);
assign dbus_addr_o[`ADDR_BUS_WIDTH-1:0] = {32{mem_en_flag || mem_en_flag_1r}} & mem_addr[`ADDR_BUS_WIDTH-1:0];
assign dbus_data_o[`DATA_BUS_WIDTH-1:0] = {32{mem_en_flag}} & mem_data[`DATA_BUS_WIDTH-1:0];
assign dbus_size_o[2:0] = {3{mem_en_flag}} & mem_size[2:0];
assign dbus_rd_o = mem_en_flag & op_load;
assign dbus_we_o = mem_en_flag & op_store;
wire [`REG_BUS_WIDTH-1:0] mau_reg_addr;
pa_dff_rst_0 #(`REG_BUS_WIDTH) dff_mau_reg_addr (clk_i, rst_n_i, `VALID, reg_waddr_wb, mau_reg_addr);
wire mau_reg_addr_vld;
pa_dff_rst_0 #(1) dff_mau_reg_addr_vld (clk_i, rst_n_i, `VALID, reg_waddr_wb_vld, mau_reg_addr_vld);
wire [`DATA_BUS_WIDTH-1:0] mau_mem_data;
wire mau_mem_data_vld;
assign mau_mem_data[`DATA_BUS_WIDTH-1:0] = mem_rdata[`DATA_BUS_WIDTH-1:0];
assign mau_mem_data_vld = mem_rdata_vld;
// rtu module work under ID/WB state, include regfile and csrfile
wire [`REG_BUS_WIDTH-1:0] rtu_reg_waddr;
wire rtu_reg_waddr_vld;
wire [`DATA_BUS_WIDTH-1:0] rtu_reg_wdata;
wire [`CSR_BUS_WIDTH-1:0] rtu_csr_waddr;
wire rtu_csr_waddr_vld;
wire [`DATA_BUS_WIDTH-1:0] rtu_csr_wdata;
assign rtu_reg_waddr[`REG_BUS_WIDTH-1:0] = mau_mem_data_vld ? mau_reg_addr[`REG_BUS_WIDTH-1:0] // from memory
: reg_waddr_wb[`REG_BUS_WIDTH-1:0]; // from exu
assign rtu_reg_waddr_vld = mau_mem_data_vld ? (mau_reg_addr_vld && !mem_en_flag) // from memory
: reg_waddr_wb_vld; // from exu
assign rtu_reg_wdata[`DATA_BUS_WIDTH-1:0] = mau_mem_data_vld ? mau_mem_data[`DATA_BUS_WIDTH-1:0] // from memory, data
: iresult[`DATA_BUS_WIDTH-1:0]; // from exu, data
assign rtu_csr_waddr[`CSR_BUS_WIDTH-1:0] = csr_waddr[`CSR_BUS_WIDTH-1:0];
assign rtu_csr_waddr_vld = csr_waddr_vld;
assign rtu_csr_wdata[`DATA_BUS_WIDTH-1:0] = csr_wdata[`DATA_BUS_WIDTH-1:0];
pa_core_rtu u_pa_core_rtu (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.reg1_raddr_i (reg1_raddr),
.reg2_raddr_i (reg2_raddr),
.reg_waddr_i (rtu_reg_waddr),
.reg_waddr_vld_i (rtu_reg_waddr_vld),
.reg_wdata_i (rtu_reg_wdata),
.reg1_rdata_o (reg1_rdata),
.reg2_rdata_o (reg2_rdata),
.csr_mtvec_o (csr_mtvec_data),
.csr_mepc_o (csr_mepc_data),
.csr_mstatus_o (csr_mstatus_data),
.csr_raddr_i (exu_csr_addr),
.csr_waddr_i (rtu_csr_waddr),
.csr_waddr_vld_i (rtu_csr_waddr_vld),
.csr_wdata_i (rtu_csr_wdata),
.csr_rdata_o (exu_csr_rdata)
);
endmodule

View File

@ -0,0 +1,207 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_core_xreg (
input wire clk_i,
input wire rst_n_i,
input wire [`REG_BUS_WIDTH-1:0] reg1_raddr_i,
input wire [`REG_BUS_WIDTH-1:0] reg2_raddr_i,
input wire [`REG_BUS_WIDTH-1:0] reg_waddr_i,
input wire reg_waddr_vld_i,
input wire [`DATA_BUS_WIDTH-1:0] reg_wdata_i,
output wire [`DATA_BUS_WIDTH-1:0] reg1_rdata_o,
output wire [`DATA_BUS_WIDTH-1:0] reg2_rdata_o
);
reg [`DATA_BUS_WIDTH-1:0] _x0 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x1 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x2 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x3 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x4 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x5 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x6 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x7 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x8 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x9 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x10 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x11 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x12 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x13 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x14 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x15 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x16 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x17 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x18 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x19 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x20 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x21 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x22 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x23 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x24 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x25 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x26 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x27 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x28 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x29 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x30 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _x31 = `ZERO_WORD;
reg [`DATA_BUS_WIDTH-1:0] _rs1;
reg [`DATA_BUS_WIDTH-1:0] _rs2;
always @ (posedge clk_i) begin
if (reg_waddr_vld_i) begin
case (reg_waddr_i[4:0])
5'h00 : _x0 <= `ZERO_WORD;
5'h01 : _x1 <= reg_wdata_i;
5'h02 : _x2 <= reg_wdata_i;
5'h03 : _x3 <= reg_wdata_i;
5'h04 : _x4 <= reg_wdata_i;
5'h05 : _x5 <= reg_wdata_i;
5'h06 : _x6 <= reg_wdata_i;
5'h07 : _x7 <= reg_wdata_i;
5'h08 : _x8 <= reg_wdata_i;
5'h09 : _x9 <= reg_wdata_i;
5'h0a : _x10 <= reg_wdata_i;
5'h0b : _x11 <= reg_wdata_i;
5'h0c : _x12 <= reg_wdata_i;
5'h0d : _x13 <= reg_wdata_i;
5'h0e : _x14 <= reg_wdata_i;
5'h0f : _x15 <= reg_wdata_i;
5'h10 : _x16 <= reg_wdata_i;
5'h11 : _x17 <= reg_wdata_i;
5'h12 : _x18 <= reg_wdata_i;
5'h13 : _x19 <= reg_wdata_i;
5'h14 : _x20 <= reg_wdata_i;
5'h15 : _x21 <= reg_wdata_i;
5'h16 : _x22 <= reg_wdata_i;
5'h17 : _x23 <= reg_wdata_i;
5'h18 : _x24 <= reg_wdata_i;
5'h19 : _x25 <= reg_wdata_i;
5'h1a : _x26 <= reg_wdata_i;
5'h1b : _x27 <= reg_wdata_i;
5'h1c : _x28 <= reg_wdata_i;
5'h1d : _x29 <= reg_wdata_i;
5'h1e : _x30 <= reg_wdata_i;
5'h1f : _x31 <= reg_wdata_i;
endcase
end
end
always @ (*) begin
if (reg_waddr_vld_i && (reg1_raddr_i == reg_waddr_i)) begin
if (reg1_raddr_i == 5'h00) begin
_rs1 = `ZERO_WORD;
end
else begin
_rs1 = reg_wdata_i;
end
end
else begin
case (reg1_raddr_i[4:0])
5'h00 : _rs1 = _x0;
5'h01 : _rs1 = _x1;
5'h02 : _rs1 = _x2;
5'h03 : _rs1 = _x3;
5'h04 : _rs1 = _x4;
5'h05 : _rs1 = _x5;
5'h06 : _rs1 = _x6;
5'h07 : _rs1 = _x7;
5'h08 : _rs1 = _x8;
5'h09 : _rs1 = _x9;
5'h0a : _rs1 = _x10;
5'h0b : _rs1 = _x11;
5'h0c : _rs1 = _x12;
5'h0d : _rs1 = _x13;
5'h0e : _rs1 = _x14;
5'h0f : _rs1 = _x15;
5'h10 : _rs1 = _x16;
5'h11 : _rs1 = _x17;
5'h12 : _rs1 = _x18;
5'h13 : _rs1 = _x19;
5'h14 : _rs1 = _x20;
5'h15 : _rs1 = _x21;
5'h16 : _rs1 = _x22;
5'h17 : _rs1 = _x23;
5'h18 : _rs1 = _x24;
5'h19 : _rs1 = _x25;
5'h1a : _rs1 = _x26;
5'h1b : _rs1 = _x27;
5'h1c : _rs1 = _x28;
5'h1d : _rs1 = _x29;
5'h1e : _rs1 = _x30;
5'h1f : _rs1 = _x31;
endcase
end
end
always @ (*) begin
if (reg_waddr_vld_i && (reg2_raddr_i == reg_waddr_i)) begin
if (reg2_raddr_i == 5'h00) begin
_rs2 = `ZERO_WORD;
end
else begin
_rs2 = reg_wdata_i;
end
end
else begin
case (reg2_raddr_i[4:0])
5'h00 : _rs2 = _x0;
5'h01 : _rs2 = _x1;
5'h02 : _rs2 = _x2;
5'h03 : _rs2 = _x3;
5'h04 : _rs2 = _x4;
5'h05 : _rs2 = _x5;
5'h06 : _rs2 = _x6;
5'h07 : _rs2 = _x7;
5'h08 : _rs2 = _x8;
5'h09 : _rs2 = _x9;
5'h0a : _rs2 = _x10;
5'h0b : _rs2 = _x11;
5'h0c : _rs2 = _x12;
5'h0d : _rs2 = _x13;
5'h0e : _rs2 = _x14;
5'h0f : _rs2 = _x15;
5'h10 : _rs2 = _x16;
5'h11 : _rs2 = _x17;
5'h12 : _rs2 = _x18;
5'h13 : _rs2 = _x19;
5'h14 : _rs2 = _x20;
5'h15 : _rs2 = _x21;
5'h16 : _rs2 = _x22;
5'h17 : _rs2 = _x23;
5'h18 : _rs2 = _x24;
5'h19 : _rs2 = _x25;
5'h1a : _rs2 = _x26;
5'h1b : _rs2 = _x27;
5'h1c : _rs2 = _x28;
5'h1d : _rs2 = _x29;
5'h1e : _rs2 = _x30;
5'h1f : _rs2 = _x31;
endcase
end
end
assign reg1_rdata_o[`DATA_BUS_WIDTH-1:0] = _rs1[`DATA_BUS_WIDTH-1:0];
assign reg2_rdata_o[`DATA_BUS_WIDTH-1:0] = _rs2[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
// memory model define(only choose one)
`ifdef TESTBENCH_VCS
`define MEMORY_MODEL_REG
`else
`define MEMORY_MODEL_BRAM
`endif
// xtal clock freq define(cpu clock may be divided)
`define XTAL_FREQ_HZ 32'd27_000_000
// core clock freq define
`define CORE_FREQ_HZ 32'd10_125_000
// uart baud rate define(fixed)
`define UART_BAUD 32'd115200
// memory size define(KByte)
`ifdef MEMORY_MODEL_REG
`define MEM_SIZE 32'd32
`endif
// bus width
`define ADDR_BUS_WIDTH 8'd32
`define DATA_BUS_WIDTH 8'd32
`define REG_BUS_WIDTH 8'd5
`define CSR_BUS_WIDTH 8'd12
// data width(bit)
`define INT_WIDTH 8'd32
// cpu reset pc address
`define RESET_PC_ADDR 32'h0000_0000
// instruct data define
`define INST_DATA_NOP 32'h0000_0000
// default data define
`define ZERO_WORD 32'h0000_0000
// valid signal value define
`define VALID 1'b1
`define INVALID 1'b0
// pin level define
`define LEVEL_HIGH 1'b1
`define LEVEL_LOW 1'b0
// csr register address define
`define CSR_NULL 12'h000
`define CSR_MTVEC 12'h305
`define CSR_MEPC 12'h341
`define CSR_MCAUSE 12'h342
`define CSR_MIE 12'h304
`define CSR_MIP 12'h344
`define CSR_MTVAL 12'h343
`define CSR_MSCRATCH 12'h340
`define CSR_MSCRATCHCSWL 12'h349
`define CSR_MSTATUS 12'h300
`define CSR_CYCLEH 12'hc80
`define CSR_CYCLE 12'hc00
// instruc define
`define INST_SET_WIDTH 8'd8
`define INST_SET_NULL 8'b0000_0000
`define INST_SET_RV32I 8'b0000_0001
`define INST_SET_RV32M 8'b0000_0010
`define INST_SET_RV32FD 8'b0000_0000
`define INST_TYPE_WIDTH 8'd8
`define INST_TYPE_NULL 8'b0000_0000
`define INST_TYPE_CSR 8'b0000_0001
`define INST_TYPE_R 8'b0000_0010
`define INST_TYPE_I 8'b0000_0100
`define INST_TYPE_S 8'b0000_1000
`define INST_TYPE_B 8'b0001_0000
`define INST_TYPE_U 8'b0010_0000
`define INST_TYPE_J 8'b0100_0000
`define INST_FUNC_WIDTH 8'd32
`define INST_FUNC_NULL 32'b0_0_00_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_ADD 32'b0_0_00_0000_1000_0000_0000_0000_0000_0000
`define INST_FUNC_SUB 32'b0_0_00_0000_0100_0000_0000_0000_0000_0000
`define INST_FUNC_SLL 32'b0_0_00_0000_0010_0000_0000_0000_0000_0000
`define INST_FUNC_SRL 32'b0_0_00_0000_0001_0000_0000_0000_0000_0000
`define INST_FUNC_SRA 32'b0_0_00_0000_0000_1000_0000_0000_0000_0000
`define INST_FUNC_OR 32'b0_0_00_0000_0000_0100_0000_0000_0000_0000
`define INST_FUNC_AND 32'b0_0_00_0000_0000_0010_0000_0000_0000_0000
`define INST_FUNC_XOR 32'b0_0_00_0000_0000_0001_0000_0000_0000_0000
`define INST_FUNC_SLT 32'b0_0_00_0000_0000_0000_1000_0000_0000_0000
`define INST_FUNC_LOAD 32'b0_0_00_0000_0000_0000_0100_0000_0000_0000
`define INST_FUNC_STORE 32'b0_0_00_0000_0000_0000_0010_0000_0000_0000
`define INST_FUNC_FENCE 32'b0_0_00_0000_0000_0000_0001_0000_0000_0000
`define INST_FUNC_B 32'b0_0_00_0000_0000_0000_0000_1000_0000_0000
`define INST_FUNC_JAL 32'b0_0_00_0000_0000_0000_0000_0100_0000_0000
`define INST_FUNC_JALR 32'b0_0_00_0000_0000_0000_0000_0010_0000_0000
`define INST_FUNC_AUIPC 32'b0_0_00_0000_0000_0000_0000_0001_0000_0000
`define INST_FUNC_LUI 32'b0_0_00_0000_0000_0000_0000_0000_1000_0000
`define INST_FUNC_ECALL 32'b0_0_00_0000_0000_0000_0000_0000_0100_0000
`define INST_FUNC_EBREAK 32'b0_0_00_0000_0000_0000_0000_0000_0010_0000
`define INST_FUNC_MRET 32'b0_0_00_0000_0000_0000_0000_0000_0001_0000
`define INST_FUNC_WFI 32'b0_0_00_0000_0000_0000_0000_0000_0000_1000
`define INST_FUNC_CSRRW 32'b0_0_00_0000_0000_0000_0000_0000_0000_0100
`define INST_FUNC_CSRRS 32'b0_0_00_0000_0000_0000_0000_0000_0000_0010
`define INST_FUNC_CSRRC 32'b0_0_00_0000_0000_0000_0000_0000_0000_0001
`define INST_FUNC_MUL 32'b0_0_00_0000_1000_0000_0000_0000_0000_0000
`define INST_FUNC_DIV 32'b0_0_00_0000_0100_0000_0000_0000_0000_0000
`define INST_FUNC_REM 32'b0_0_00_0000_0010_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_UNSIGN 32'b1_0_00_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_IMM 32'b0_1_00_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_HIGH 32'b0_1_00_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_BYTE 32'b0_0_01_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_HALF 32'b0_0_10_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_U1 32'b1_0_01_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_U2 32'b1_0_10_0000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_EQ 32'b0_0_00_1000_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_NE 32'b0_0_00_0100_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_LT 32'b0_0_00_0010_0000_0000_0000_0000_0000_0000
`define INST_FUNC_SUFFIX_GT 32'b0_0_00_0001_0000_0000_0000_0000_0000_0000
`define INST_LB 3'b000
`define INST_LH 3'b001
`define INST_LW 3'b010
`define INST_LBU 3'b100
`define INST_LHU 3'b101
`define INST_FENCE 3'b000
`define INST_FENCEI 3'b001
`define INST_ADD 3'b000 // INST_SUB
`define INST_SLL 3'b001
`define INST_SLT 3'b010
`define INST_SLTU 3'b011
`define INST_XOR 3'b100
`define INST_SRL 3'b101 // INST_SRA
`define INST_OR 3'b110
`define INST_AND 3'b111
`define INST_SB 3'b000
`define INST_SH 3'b001
`define INST_SW 3'b010
`define INST_BEQ 3'b000
`define INST_BNE 3'b001
`define INST_BLT 3'b100
`define INST_BGE 3'b101
`define INST_BLTU 3'b110
`define INST_BGEU 3'b111
`define INST_ECALL 3'b000 // INST_EBREAK INST_EBREAK INST_MRET INST_WFI
`define INST_CSRRW 3'b001
`define INST_CSRRS 3'b010
`define INST_CSRRC 3'b011
`define INST_CSRRWI 3'b101
`define INST_CSRRSI 3'b110
`define INST_CSRRCI 3'b111
`define INST_MUL 3'b000
`define INST_MULH 3'b001
`define INST_MULHSU 3'b010
`define INST_MULHU 3'b011
`define INST_DIV 3'b100
`define INST_DIVU 3'b101
`define INST_REM 3'b110
`define INST_REMU 3'b111

View File

@ -0,0 +1,246 @@
`timescale 1ns / 1ps
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "./pa_chip_param.v"
`endif
module pa_chip_top (
input wire clk_i,
input wire rst_n_i,
output wire clk_o,
inout wire gpio_PA0,
inout wire gpio_PA1,
inout wire gpio_PA2,
inout wire gpio_PA3,
inout wire gpio_PA4,
inout wire gpio_PA5,
inout wire gpio_PA6,
inout wire gpio_PA7,
inout wire gpio_PA8,
inout wire gpio_PA9,
inout wire gpio_PA10,
inout wire gpio_PA11,
inout wire gpio_PA12,
inout wire gpio_PA13,
input wire gpio_PA14,
output wire gpio_PA15
);
wire clk_out;
wire rst_out_n;
Gowin_rPLL _clock_0 (
.clkout(clk_out), //output clkout
.lock(rst_out_n), //output lock
.reset(~rst_n_i), //input reset
.clkin(clk_i) //input clkin
);
assign clk_o = clk_out;
wire [`ADDR_BUS_WIDTH-1:0] m0_addr;
wire [`DATA_BUS_WIDTH-1:0] m0_rdata;
wire [`ADDR_BUS_WIDTH-1:0] m1_addr;
wire m1_rd;
wire m1_we;
wire [2:0] m1_size;
wire [`DATA_BUS_WIDTH-1:0] m1_wdata;
wire [`DATA_BUS_WIDTH-1:0] m1_rdata;
wire s0_rd;
wire s0_we;
wire [`DATA_BUS_WIDTH-1:0] s0_data;
wire s1_rd;
wire s1_we;
wire [`DATA_BUS_WIDTH-1:0] s1_data;
wire s2_rd;
wire s2_we;
wire [`DATA_BUS_WIDTH-1:0] s2_data;
wire s3_rd;
wire s3_we;
wire [`DATA_BUS_WIDTH-1:0] s3_data;
wire s4_rd;
wire s4_we;
wire [`DATA_BUS_WIDTH-1:0] s4_data;
wire s5_rd;
wire s5_we;
wire [`DATA_BUS_WIDTH-1:0] s5_data;
wire s6_rd;
wire s6_we;
wire [`DATA_BUS_WIDTH-1:0] s6_data;
wire irq_flag;
pa_core_top u_pa_core_top (
.clk_i (clk_out),
.rst_n_i (rst_out_n),
.irq_i (irq_flag),
.ibus_addr_o (m0_addr),
.ibus_data_i (m0_rdata),
.dbus_addr_o (m1_addr),
.dbus_rd_o (m1_rd),
.dbus_we_o (m1_we),
.dbus_size_o (m1_size),
.dbus_data_o (m1_wdata),
.dbus_data_i (m1_rdata)
);
pa_soc_rbm u_pa_soc_rbm1 (
.m_addr_i (m1_addr),
.m_data_o (m1_rdata),
.m_we_i (m1_we),
.m_rd_i (m1_rd),
// 0x0000_0000 ~ 0x0fff_ffff
.s0_data_i (s0_data),
.s0_we_o (s0_we),
.s0_rd_o (s0_rd),
// 0x1000_0000 ~ 0x1fff_ffff
.s1_data_i (s1_data),
.s1_we_o (s1_we),
.s1_rd_o (s1_rd),
// 0x2000_0000 ~ 0x2fff_ffff
.s2_data_i (s2_data),
.s2_we_o (s2_we),
.s2_rd_o (s2_rd),
// 0x3000_0000 ~ 0x3fff_ffff
.s3_data_i (s3_data),
.s3_we_o (s3_we),
.s3_rd_o (s3_rd),
// 0x4000_0000 ~ 0x4fff_ffff
.s4_data_i (s4_data),
.s4_we_o (s4_we),
.s4_rd_o (s4_rd),
// 0x5000_0000 ~ 0x5fff_ffff
.s5_data_i (s5_data),
.s5_we_o (s5_we),
.s5_rd_o (s5_rd),
// 0x6000_0000 ~ 0x6fff_ffff
.s6_data_i (s6_data),
.s6_we_o (s6_we),
.s6_rd_o (s6_rd)
);
pa_perips_tcm2 u_pa_perips_rom (
.clk_i (clk_out),
.rst_n_i (rst_out_n),
.addr1_i (m1_addr),
.rd1_i (s0_rd),
.we1_i (s0_we),
.size1_i (m1_size),
.data1_i (m1_wdata),
.data1_o (s0_data),
.addr2_i (m0_addr),
.rd2_i (1'b1),
.data2_o (m0_rdata)
);
pa_perips_tcm u_pa_perips_ram (
.clk_i (clk_out),
.rst_n_i (rst_out_n),
.addr1_i (m1_addr),
.rd1_i (s1_rd),
.we1_i (s1_we),
.size1_i (m1_size),
.data1_i (m1_wdata),
.data1_o (s1_data),
.addr2_i (32'b0),
.rd2_i (1'b0),
.data2_o ()
);
pa_perips_timer u_pa_perips_timer1 (
.clk_i (clk_out),
.rst_n_i (rst_out_n),
.addr_i (m1_addr[7:0]),
.data_rd_i (s2_rd),
.data_we_i (s2_we),
.data_i (m1_wdata),
.data_o (s2_data),
.irq_o (irq_flag)
);
pa_perips_uart u_pa_perips_uart1 (
.clk_i (clk_out),
.rst_n_i (rst_out_n),
.addr_i (m1_addr[7:0]),
.data_rd_i (s3_rd),
.data_we_i (s3_we),
.data_i (m1_wdata),
.data_o (s3_data),
.pad_rxd (gpio_PA14),
.pad_txd (gpio_PA15)
);
pa_perips_gpio u_pa_perips_gpio1 (
.clk_i (clk_out),
.rst_n_i (rst_out_n),
.addr_i (m1_addr[7:0]),
.data_rd_i (s4_rd),
.data_we_i (s4_we),
.data_i (m1_wdata),
.data_o (s4_data),
.pad_PA0 (gpio_PA0),
.pad_PA1 (gpio_PA1),
.pad_PA2 (gpio_PA2),
.pad_PA3 (gpio_PA3),
.pad_PA4 (gpio_PA4),
.pad_PA5 (gpio_PA5),
.pad_PA6 (gpio_PA6),
.pad_PA7 (gpio_PA7),
.pad_PA8 (gpio_PA8),
.pad_PA9 (gpio_PA9),
.pad_PA10 (gpio_PA10),
.pad_PA11 (gpio_PA11),
.pad_PA12 (gpio_PA12),
.pad_PA13 (gpio_PA13),
.pad_PA14 (),
.pad_PA15 ()
);
assign s5_data[`DATA_BUS_WIDTH-1:0] = 32'b0;
assign s6_data[`DATA_BUS_WIDTH-1:0] = 32'b0;
endmodule

View File

@ -0,0 +1,233 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-12-23 Lyons first version
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_perips_gpio (
input wire clk_i,
input wire rst_n_i,
input wire [7:0] addr_i,
input wire data_rd_i,
input wire data_we_i,
input wire [`DATA_BUS_WIDTH-1:0] data_i,
output wire [`DATA_BUS_WIDTH-1:0] data_o,
inout wire pad_PA0,
inout wire pad_PA1,
inout wire pad_PA2,
inout wire pad_PA3,
inout wire pad_PA4,
inout wire pad_PA5,
inout wire pad_PA6,
inout wire pad_PA7,
inout wire pad_PA8,
inout wire pad_PA9,
inout wire pad_PA10,
inout wire pad_PA11,
inout wire pad_PA12,
inout wire pad_PA13,
inout wire pad_PA14,
inout wire pad_PA15
);
localparam GPIO_REG_CR = 8'h00;
localparam GPIO_REG_IN = 8'h04;
localparam GPIO_REG_OUT = 8'h08;
localparam GPIO_REG_RSVD = 8'h0c;
localparam GPIO_REG_OBIT = 8'h10;
// [15:0] : direction, 0:out, 1:in
reg [`DATA_BUS_WIDTH-1:0] _gpio_cr;
// [15:0] : input bit
reg [`DATA_BUS_WIDTH-1:0] _gpio_in;
// [15:0] : output bit
reg [`DATA_BUS_WIDTH-1:0] _gpio_out;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_gpio_cr <= 32'h0000_4400;
_gpio_out <= 32'h0000_fff7;
end
else begin
if (data_we_i) begin
case (addr_i[7:0])
GPIO_REG_CR : _gpio_cr <= {16'b0, data_i[15:0]};
GPIO_REG_OUT : _gpio_out <= {16'b0, data_i[15:0]};
GPIO_REG_OBIT + 4*0 : _gpio_out[0 ] <= data_i[0];
GPIO_REG_OBIT + 4*1 : _gpio_out[1 ] <= data_i[0];
GPIO_REG_OBIT + 4*2 : _gpio_out[2 ] <= data_i[0];
GPIO_REG_OBIT + 4*3 : _gpio_out[3 ] <= data_i[0];
GPIO_REG_OBIT + 4*4 : _gpio_out[4 ] <= data_i[0];
GPIO_REG_OBIT + 4*5 : _gpio_out[5 ] <= data_i[0];
GPIO_REG_OBIT + 4*6 : _gpio_out[6 ] <= data_i[0];
GPIO_REG_OBIT + 4*7 : _gpio_out[7 ] <= data_i[0];
GPIO_REG_OBIT + 4*8 : _gpio_out[8 ] <= data_i[0];
GPIO_REG_OBIT + 4*9 : _gpio_out[9 ] <= data_i[0];
GPIO_REG_OBIT + 4*10 : _gpio_out[10] <= data_i[0];
GPIO_REG_OBIT + 4*11 : _gpio_out[11] <= data_i[0];
GPIO_REG_OBIT + 4*12 : _gpio_out[12] <= data_i[0];
GPIO_REG_OBIT + 4*13 : _gpio_out[13] <= data_i[0];
GPIO_REG_OBIT + 4*14 : _gpio_out[14] <= data_i[0];
GPIO_REG_OBIT + 4*15 : _gpio_out[15] <= data_i[0];
endcase
end
end
end
reg [`DATA_BUS_WIDTH-1:0] _data = `ZERO_WORD;
always @ (posedge clk_i) begin
if (data_rd_i) begin
case (addr_i[7:0])
GPIO_REG_CR : _data <= _gpio_cr;
GPIO_REG_IN : _data <= _gpio_in;
default : _data <= `ZERO_WORD;
endcase
end
end
wire [`DATA_BUS_WIDTH-1:0] pad_PIn;
IOBUF uut_0 (
.O (pad_PIn[0]),
.IO (pad_PA0),
.I (_gpio_out[0]),
.OEN (_gpio_cr[0])
);
IOBUF uut_1 (
.O (pad_PIn[1]),
.IO (pad_PA1),
.I (_gpio_out[1]),
.OEN (_gpio_cr[1])
);
IOBUF uut_2 (
.O (pad_PIn[2]),
.IO (pad_PA2),
.I (_gpio_out[2]),
.OEN (_gpio_cr[2])
);
IOBUF uut_3 (
.O (pad_PIn[3]),
.IO (pad_PA3),
.I (_gpio_out[3]),
.OEN (_gpio_cr[3])
);
IOBUF uut_4 (
.O (pad_PIn[4]),
.IO (pad_PA4),
.I (_gpio_out[4]),
.OEN (_gpio_cr[4])
);
IOBUF uut_5 (
.O (pad_PIn[5]),
.IO (pad_PA5),
.I (_gpio_out[5]),
.OEN (_gpio_cr[5])
);
IOBUF uut_6 (
.O (pad_PIn[6]),
.IO (pad_PA6),
.I (_gpio_out[6]),
.OEN (_gpio_cr[6])
);
IOBUF uut_7 (
.O (pad_PIn[7]),
.IO (pad_PA7),
.I (_gpio_out[7]),
.OEN (_gpio_cr[7])
);
IOBUF uut_8 (
.O (pad_PIn[8]),
.IO (pad_PA8),
.I (_gpio_out[8]),
.OEN (_gpio_cr[8])
);
IOBUF uut_9 (
.O (pad_PIn[9]),
.IO (pad_PA9),
.I (_gpio_out[9]),
.OEN (_gpio_cr[9])
);
IOBUF uut_10 (
.O (pad_PIn[10]),
.IO (pad_PA10),
.I (_gpio_out[10]),
.OEN (_gpio_cr[10])
);
IOBUF uut_11 (
.O (pad_PIn[11]),
.IO (pad_PA11),
.I (_gpio_out[11]),
.OEN (_gpio_cr[11])
);
IOBUF uut_12 (
.O (pad_PIn[12]),
.IO (pad_PA12),
.I (_gpio_out[12]),
.OEN (_gpio_cr[12])
);
IOBUF uut_13 (
.O (pad_PIn[13]),
.IO (pad_PA13),
.I (_gpio_out[13]),
.OEN (_gpio_cr[13])
);
// IOBUF uut_14 (
// .O (pad_PIn[14]),
// .IO (pad_PA14),
// .I (_gpio_out[14]),
// .OEN (_gpio_cr[14])
// );
// IOBUF uut_15 (
// .O (pad_PIn[15]),
// .IO (pad_PA15),
// .I (_gpio_out[15]),
// .OEN (_gpio_cr[15])
// );
assign pad_PIn[31:14] = 18'b0;
always @ (posedge clk_i) begin
if (!rst_n_i) begin
_gpio_in <= `ZERO_WORD;
end
else begin
_gpio_in <= pad_PIn;
end
end
assign data_o[`DATA_BUS_WIDTH-1:0] = _data[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_perips_tcm (
input wire clk_i,
input wire rst_n_i,
input wire [`ADDR_BUS_WIDTH-1:0] addr1_i,
input wire rd1_i,
input wire we1_i,
input wire [2:0] size1_i,
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
output wire [`DATA_BUS_WIDTH-1:0] data1_o,
input wire [`ADDR_BUS_WIDTH-1:0] addr2_i,
input wire rd2_i,
output wire [`DATA_BUS_WIDTH-1:0] data2_o
);
wire [`ADDR_BUS_WIDTH-1:0] index1;
wire [`ADDR_BUS_WIDTH-1:0] index2;
assign index1[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr1_i[27:2]};
assign index2[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr2_i[27:2]};
reg [3:0] addr_mask;
wire size_word;
wire size_half;
assign size_word = size1_i[2];
assign size_half = size1_i[1];
always @ (*) begin
case (addr1_i[1:0])
2'b00 : addr_mask[3:0] <= {size_word, size_word, (size_word || size_half), 1'b1};
2'b01 : addr_mask[3:0] <= {4'b0010};
2'b10 : addr_mask[3:0] <= {size_half, 3'b100};
2'b11 : addr_mask[3:0] <= {4'b1000};
endcase
end
wire [`DATA_BUS_WIDTH-1:0] _data1;
wire [`DATA_BUS_WIDTH-1:0] _data2;
Gowin_DPB_8x4k _ram_3 (
.douta(_data1[31:24]), //output [7:0] douta
.doutb(_data2[31:24]), //output [7:0] doutb
.clka(clk_i), //input clka
.ocea(`VALID), //input ocea
.cea(`VALID), //input cea
.reseta(~rst_n_i), //input reseta
.wrea(we1_i && addr_mask[3]), //input wrea
.clkb(clk_i), //input clkb
.oceb(`VALID), //input oceb
.ceb(`VALID), //input ceb
.resetb(~rst_n_i), //input resetb
.wreb(1'b0), //input wreb
.ada(addr1_i[13:2]), //input [11:0] ada
.dina(data1_i[31:24]), //input [7:0] dina
.adb(addr2_i[13:2]), //input [11:0] adb
.dinb(8'b0) //input [7:0] dinb
);
Gowin_DPB_8x4k _ram_2 (
.douta(_data1[23:16]), //output [7:0] douta
.doutb(_data2[23:16]), //output [7:0] doutb
.clka(clk_i), //input clka
.ocea(`VALID), //input ocea
.cea(`VALID), //input cea
.reseta(~rst_n_i), //input reseta
.wrea(we1_i && addr_mask[2]), //input wrea
.clkb(clk_i), //input clkb
.oceb(`VALID), //input oceb
.ceb(`VALID), //input ceb
.resetb(~rst_n_i), //input resetb
.wreb(1'b0), //input wreb
.ada(addr1_i[13:2]), //input [11:0] ada
.dina(data1_i[23:16]), //input [7:0] dina
.adb(addr2_i[13:2]), //input [11:0] adb
.dinb(8'b0) //input [7:0] dinb
);
Gowin_DPB_8x4k _ram_1 (
.douta(_data1[15:8]), //output [7:0] douta
.doutb(_data2[15:8]), //output [7:0] doutb
.clka(clk_i), //input clka
.ocea(`VALID), //input ocea
.cea(`VALID), //input cea
.reseta(~rst_n_i), //input reseta
.wrea(we1_i && addr_mask[1]), //input wrea
.clkb(clk_i), //input clkb
.oceb(`VALID), //input oceb
.ceb(`VALID), //input ceb
.resetb(~rst_n_i), //input resetb
.wreb(1'b0), //input wreb
.ada(addr1_i[13:2]), //input [11:0] ada
.dina(data1_i[15:8]), //input [7:0] dina
.adb(addr2_i[13:2]), //input [11:0] adb
.dinb(8'b0) //input [7:0] dinb
);
Gowin_DPB_8x4k _ram_0 (
.douta(_data1[7:0]), //output [7:0] douta
.doutb(_data2[7:0]), //output [7:0] doutb
.clka(clk_i), //input clka
.ocea(`VALID), //input ocea
.cea(`VALID), //input cea
.reseta(~rst_n_i), //input reseta
.wrea(we1_i && addr_mask[0]), //input wrea
.clkb(clk_i), //input clkb
.oceb(`VALID), //input oceb
.ceb(`VALID), //input ceb
.resetb(~rst_n_i), //input resetb
.wreb(1'b0), //input wreb
.ada(addr1_i[13:2]), //input [11:0] ada
.dina(data1_i[7:0]), //input [7:0] dina
.adb(addr2_i[13:2]), //input [11:0] adb
.dinb(8'b0) //input [7:0] dinb
);
assign data1_o[`DATA_BUS_WIDTH-1:0] = _data1[`DATA_BUS_WIDTH-1:0];
assign data2_o[`DATA_BUS_WIDTH-1:0] = _data2[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
* 2022-07-01 Lyons add pa_perips_tcm2 for rom
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_perips_tcm2 (
input wire clk_i,
input wire rst_n_i,
input wire [`ADDR_BUS_WIDTH-1:0] addr1_i,
input wire rd1_i,
input wire we1_i,
input wire [2:0] size1_i,
input wire [`DATA_BUS_WIDTH-1:0] data1_i,
output wire [`DATA_BUS_WIDTH-1:0] data1_o,
input wire [`ADDR_BUS_WIDTH-1:0] addr2_i,
input wire rd2_i,
output wire [`DATA_BUS_WIDTH-1:0] data2_o
);
`ifdef MEMORY_MODEL_REG
reg [7:0] _ram[0:`MEM_SIZE*1024-1];
wire [`ADDR_BUS_WIDTH-1:0] index1;
wire [`ADDR_BUS_WIDTH-1:0] index2;
assign index1[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr1_i[27:2]};
assign index2[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr2_i[27:2]};
reg [`DATA_BUS_WIDTH-1:0] _data1;
reg [`DATA_BUS_WIDTH-1:0] _data2;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_data1[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
end
else if (rd1_i) begin
_data1[`DATA_BUS_WIDTH-1:0] = {_ram[index1*4+3], _ram[index1*4+2], _ram[index1*4+1], _ram[index1*4+0]};
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_data2[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
end
else if (rd2_i) begin
_data2[`DATA_BUS_WIDTH-1:0] = {_ram[index2*4+3], _ram[index2*4+2], _ram[index2*4+1], _ram[index2*4+0]};
end
end
`endif // `ifdef MEMORY_MODEL_REG
`ifdef MEMORY_MODEL_BRAM
wire [`DATA_BUS_WIDTH-1:0] _data1;
wire [`DATA_BUS_WIDTH-1:0] _data2;
Gowin_DPB_32x8k _rom_0 (
.douta(_data1), //output [31:0] douta
.doutb(_data2), //output [31:0] doutb
.clka(clk_i), //input clka
.ocea(`VALID), //input ocea
.cea(`VALID), //input cea
.reseta(~rst_n_i), //input reseta
.wrea(we1_i), //input wrea
.clkb(clk_i), //input clkb
.oceb(`VALID), //input oceb
.ceb(`VALID), //input ceb
.resetb(~rst_n_i), //input resetb
.wreb(1'b0), //input wreb
.ada(addr1_i[14:2]), //input [12:0] ada
.dina(data1_i), //input [31:0] dina
.adb(addr2_i[14:2]), //input [12:0] adb
.dinb(32'b0) //input [31:0] dinb
);
`endif // `ifdef MEMORY_MODEL_BRAM
assign data1_o[`DATA_BUS_WIDTH-1:0] = _data1[`DATA_BUS_WIDTH-1:0];
assign data2_o[`DATA_BUS_WIDTH-1:0] = _data2[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_perips_timer (
input wire clk_i,
input wire rst_n_i,
input wire [7:0] addr_i,
input wire data_rd_i,
input wire data_we_i,
input wire [`DATA_BUS_WIDTH-1:0] data_i,
output wire [`DATA_BUS_WIDTH-1:0] data_o,
output wire irq_o
);
localparam TIMER_REG_CR = 8'h00;
localparam TIMER_REG_SR = 8'h04;
localparam TIMER_REG_PSC = 8'h08;
localparam TIMER_REG_LOAD = 8'h0c;
localparam TIMER_REG_COUNT = 8'h10;
// [0]: enbale
reg [`DATA_BUS_WIDTH-1:0] _timer_cr;
// [0]: timing-up flag
reg [`DATA_BUS_WIDTH-1:0] _timer_sr;
// [31:0] : prescale, need sub 1
reg [`DATA_BUS_WIDTH-1:0] _timer_psc;
// [31:0] : load value
reg [`DATA_BUS_WIDTH-1:0] _timer_load;
// [31:0] : count
reg [`DATA_BUS_WIDTH-1:0] _timer_count;
reg [`DATA_BUS_WIDTH-1:0] timer_clk_cnt;
wire timer_clk_timeup;
assign timer_clk_timeup = (timer_clk_cnt == _timer_psc[31:0]);
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
timer_clk_cnt <= `ZERO_WORD;
end
else if (_timer_cr[0]) begin
if (timer_clk_timeup) begin
timer_clk_cnt <= `ZERO_WORD;
end
else begin
timer_clk_cnt <= timer_clk_cnt + 32'h1;
end
end
else begin
timer_clk_cnt <= `ZERO_WORD;
end
end
reg timer_timeup;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
timer_timeup <= 1'b0;
end
else if (_timer_cr[0]) begin
if (timer_timeup) begin
timer_timeup <= 1'b0;
end
else if (_timer_count == 32'h0) begin
timer_timeup <= 1'b1;
end
end
else begin
timer_timeup <= 1'b0;
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_timer_count <= `ZERO_WORD;
end
else if (_timer_cr[0]) begin
if (_timer_count == 32'h0) begin
_timer_count <= _timer_load; // re-load timer value
end
else if (timer_clk_timeup) begin
_timer_count <= _timer_count - 32'h1;
end
else begin
_timer_count <= _timer_count;
end
end
else begin
_timer_count <= `ZERO_WORD;
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_timer_cr <= `ZERO_WORD;
_timer_sr <= `ZERO_WORD;
_timer_psc <= `ZERO_WORD;
_timer_load <= `ZERO_WORD;
end
else begin
if (data_we_i) begin
case (addr_i[7:0])
TIMER_REG_CR : _timer_cr <= {data_i[31:0]};
TIMER_REG_SR : _timer_sr <= {data_i[31:1], (_timer_sr[0] & ~data_i[0])};
TIMER_REG_PSC : _timer_psc <= {data_i[31:0]};
TIMER_REG_LOAD : _timer_load <= {data_i[31:0]};
endcase
end
else if (_timer_sr[0]) begin
_timer_sr <= {data_i[31:1], 1'b0};
end
else begin
if (_timer_cr[0] && timer_timeup) begin
_timer_sr <= {data_i[31:1], 1'b1};
end
end
end
end
reg [`DATA_BUS_WIDTH-1:0] _data = `ZERO_WORD;
always @ (posedge clk_i) begin
if (data_rd_i) begin
case (addr_i[7:0])
TIMER_REG_CR : _data <= _timer_cr;
TIMER_REG_SR : _data <= _timer_sr;
TIMER_REG_PSC : _data <= _timer_psc;
TIMER_REG_LOAD : _data <= _timer_load;
TIMER_REG_COUNT : _data <= _timer_count;
default : _data <= `ZERO_WORD;
endcase
end
end
assign data_o[`DATA_BUS_WIDTH-1:0] = _data[`DATA_BUS_WIDTH-1:0];
assign irq_o = _timer_sr[0];
endmodule

View File

@ -0,0 +1,285 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_perips_uart (
input wire clk_i,
input wire rst_n_i,
input wire [7:0] addr_i,
input wire data_rd_i,
input wire data_we_i,
input wire [`DATA_BUS_WIDTH-1:0] data_i,
output wire [`DATA_BUS_WIDTH-1:0] data_o,
input wire pad_rxd,
output wire pad_txd
);
localparam UART_REG_CR = 8'h00;
localparam UART_REG_SR = 8'h04;
localparam UART_REG_BAUD = 8'h08;
localparam UART_REG_RXD = 8'h0c;
localparam UART_REG_TXD = 8'h10;
localparam UART_STATE_IDLE = 2'b00;
localparam UART_STATE_START = 2'b01;
localparam UART_STATE_RUN = 2'b10;
localparam UART_STATE_END = 2'b11;
// [0]: tx enbale
// [1]: rx enbale
reg [`DATA_BUS_WIDTH-1:0] _uart_cr;
// [0]: tx flag
// [1]: rx flag
reg [`DATA_BUS_WIDTH-1:0] _uart_sr;
// [31:0] : baud
reg [`DATA_BUS_WIDTH-1:0] _uart_baud;
// [31:0] : rx data
reg [`DATA_BUS_WIDTH-1:0] _uart_rxd;
// [31:0] : tx data
reg [`DATA_BUS_WIDTH-1:0] _uart_txd;
wire [`DATA_BUS_WIDTH-1:0] uart_tx_clk_cycle;
wire [`DATA_BUS_WIDTH-1:0] uart_rx_clk_cycle;
wire [`DATA_BUS_WIDTH-1:0] uart_rx_clk_cycle_d2;
reg [`DATA_BUS_WIDTH-1:0] uart_tx_clk_cnt;
reg [`DATA_BUS_WIDTH-1:0] uart_rx_clk_cnt;
wire uart_tx_clk_timeup;
wire uart_rx_clk_timeup;
// stop=1 datah...datal start=0 10bit=1
reg [19:0] uart_tx_pipe;
reg [7:0] uart_rx_pipe;
reg [1:0] uart_tx_state;
reg [1:0] uart_rx_state;
assign uart_tx_clk_cycle[`DATA_BUS_WIDTH-1:0] = (`CORE_FREQ_HZ / `UART_BAUD);
assign uart_rx_clk_cycle[`DATA_BUS_WIDTH-1:0] = (`CORE_FREQ_HZ / `UART_BAUD);
assign uart_rx_clk_cycle_d2[`DATA_BUS_WIDTH-1:0] = (`CORE_FREQ_HZ / `UART_BAUD) / 2;
assign uart_tx_clk_timeup = (uart_tx_clk_cnt == uart_tx_clk_cycle[31:0]);
assign uart_rx_clk_timeup = (uart_rx_state[1:0] == UART_STATE_START) ? (uart_rx_clk_cnt == uart_rx_clk_cycle_d2[31:0])
: (uart_rx_clk_cnt == uart_rx_clk_cycle[31:0] );
// uart tx pipeline
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_tx_clk_cnt <= `ZERO_WORD;
end
else if (uart_tx_state[1:0] == UART_STATE_IDLE) begin
uart_tx_clk_cnt <= `ZERO_WORD;
end
else if (uart_tx_clk_timeup) begin
uart_tx_clk_cnt <= `ZERO_WORD;
end
else begin
uart_tx_clk_cnt <= uart_tx_clk_cnt + 32'h1;
end
end
reg uart_tx_start;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_tx_start <= `INVALID;
end
else if (_uart_cr[0] && (addr_i[7:0] == UART_REG_TXD) && data_we_i) begin
uart_tx_start <= `VALID;
end
else if (uart_tx_state[1:0] == UART_STATE_START) begin
uart_tx_start <= `INVALID;
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_tx_state[1:0] <= UART_STATE_IDLE;
end
else if (uart_tx_start) begin
uart_tx_state[1:0] <= UART_STATE_START;
end
else if (uart_tx_clk_timeup) begin
if (uart_tx_state[1:0] == UART_STATE_START) begin
uart_tx_state[1:0] <= UART_STATE_RUN;
end
else if (uart_tx_state[1:0] == UART_STATE_RUN) begin
if (!uart_tx_pipe[0]) begin
uart_tx_state[1:0] <= UART_STATE_END;
end
end
else if (uart_tx_state[1:0] == UART_STATE_END) begin
uart_tx_state[1:0] <= UART_STATE_IDLE;
end
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_tx_pipe[19:0] <= 20'hf_ffff;
end
else if (uart_tx_clk_timeup) begin
if (_uart_cr[0]) begin
case (uart_tx_state[1:0])
UART_STATE_IDLE : uart_tx_pipe[19:0] <= {20'hf_ffff};
UART_STATE_START : uart_tx_pipe[19:0] <= {1'b1, _uart_txd[7:0], 1'b0, 10'h3ff};
UART_STATE_RUN : uart_tx_pipe[19:0] <= {1'b1, uart_tx_pipe[19:1]};
UART_STATE_END : uart_tx_pipe[19:0] <= {20'hf_ffff};
endcase
end
end
end
assign pad_txd = uart_tx_pipe[10];
// uart rx pipeline
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_rx_clk_cnt <= `ZERO_WORD;
end
else if (uart_rx_state[1:0] == UART_STATE_IDLE) begin
uart_rx_clk_cnt <= `ZERO_WORD;
end
else if (uart_rx_clk_timeup) begin
uart_rx_clk_cnt <= `ZERO_WORD;
end
else begin
uart_rx_clk_cnt <= uart_rx_clk_cnt + 32'h1;
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_rx_state[1:0] <= UART_STATE_IDLE;
end
else if (uart_rx_state[1:0] == UART_STATE_IDLE) begin
if (!pad_rxd) begin
uart_rx_state[1:0] <= UART_STATE_START;
end
end
else if (uart_rx_state[1:0] == UART_STATE_START) begin
if (!pad_rxd && uart_rx_clk_timeup) begin
uart_rx_state[1:0] <= UART_STATE_RUN;
end
end
else if (uart_rx_clk_timeup) begin
if (uart_rx_state[1:0] == UART_STATE_RUN) begin
if (!uart_rx_pipe[0]) begin
uart_rx_state[1:0] <= UART_STATE_END;
end
end
else if (uart_rx_state[1:0] == UART_STATE_END) begin
uart_rx_state[1:0] <= UART_STATE_IDLE;
end
end
end
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
uart_rx_pipe[7:0] <= 8'hff;
end
else if (_uart_cr[1]) begin
if (uart_rx_clk_timeup) begin
case (uart_rx_state[1:0])
UART_STATE_IDLE : uart_rx_pipe[7:0] <= {8'hff};
UART_STATE_START : uart_rx_pipe[7:0] <= {pad_rxd, uart_rx_pipe[7:1]};
UART_STATE_RUN : uart_rx_pipe[7:0] <= {pad_rxd, uart_rx_pipe[7:1]};
UART_STATE_END : uart_rx_pipe[7:0] <= {8'hff};
endcase
end
end
end
wire uart_tx_idle;
wire uart_rx_idle;
assign uart_tx_idle = (uart_tx_state[1:0] == UART_STATE_IDLE);
assign uart_rx_idle = (uart_rx_state[1:0] == UART_STATE_IDLE);
wire uart_tx_idle_1r;
pa_dff_rst_0 #(1) dff_uart_tx_idle_1r (clk_i, rst_n_i, `VALID, uart_tx_idle, uart_tx_idle_1r);
wire uart_rx_idle_1r;
pa_dff_rst_0 #(1) dff_uart_rx_idle_1r (clk_i, rst_n_i, `VALID, uart_rx_idle, uart_rx_idle_1r);
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
_uart_cr <= 32'h0000_0003; // enable uart rx/tx default
_uart_sr <= 32'h0000_0000;
_uart_baud <= `UART_BAUD; // read-only
_uart_rxd <= 32'hffff_ffff; // default high level
_uart_txd <= 32'hffff_ffff; // default high level
end
else if (_uart_cr[0] && (uart_tx_state[1:0] == UART_STATE_END)) begin
if (UART_REG_SR == addr_i[7:0]) begin
_uart_sr <= {data_i[31:2], (_uart_sr[1] & ~data_i[1]), 1'b1};
end
else begin
_uart_sr <= {_uart_sr[31:1], 1'b1};
end
end
else if (_uart_cr[1] && (uart_rx_state[1:0] == UART_STATE_END)) begin
if (UART_REG_SR == addr_i[7:0]) begin
_uart_sr <= {data_i[31:2], 1'b1, (_uart_sr[0] & ~data_i[0])};
end
else begin
_uart_sr <= {_uart_sr[31:2], 1'b1, _uart_sr[0]};
end
_uart_rxd <= {24'b0, uart_rx_pipe[7:0]};
end
else begin
if (data_we_i) begin
case (addr_i[7:0])
UART_REG_CR : _uart_cr <= {data_i[31:0]};
UART_REG_SR : _uart_sr <= {data_i[31:2], (_uart_sr[1] & ~data_i[1]), (_uart_sr[0] & ~data_i[0])};
UART_REG_TXD : _uart_txd <= {24'b0, data_i[7:0]};
endcase
end
end
end
reg [`DATA_BUS_WIDTH-1:0] _data = `ZERO_WORD;
always @ (posedge clk_i) begin
if (data_rd_i) begin
case (addr_i[7:0])
UART_REG_CR : _data <= {_uart_cr[31:0]};
UART_REG_SR : _data <= {_uart_sr[31:2], (uart_rx_idle_1r & _uart_sr[1]), (uart_tx_idle_1r & _uart_sr[0])};
UART_REG_BAUD : _data <= {_uart_baud[31:0]};
UART_REG_RXD : _data <= {24'b0, _uart_rxd[7:0]};
UART_REG_TXD : _data <= {24'b0, _uart_txd[7:0]};
default : _data <= {32'h0000_0000};
endcase
end
end
assign data_o[`DATA_BUS_WIDTH-1:0] = _data[`DATA_BUS_WIDTH-1:0];
endmodule

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
* 2022-04-04 Lyons v2.0
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
module pa_soc_rbm (
input wire [`ADDR_BUS_WIDTH-1:0] m_addr_i,
output reg [`DATA_BUS_WIDTH-1:0] m_data_o,
input wire m_we_i,
input wire m_rd_i,
input wire [`DATA_BUS_WIDTH-1:0] s0_data_i,
output reg s0_we_o,
output reg s0_rd_o,
input wire [`DATA_BUS_WIDTH-1:0] s1_data_i,
output reg s1_we_o,
output reg s1_rd_o,
input wire [`DATA_BUS_WIDTH-1:0] s2_data_i,
output reg s2_we_o,
output reg s2_rd_o,
input wire [`DATA_BUS_WIDTH-1:0] s3_data_i,
output reg s3_we_o,
output reg s3_rd_o,
input wire [`DATA_BUS_WIDTH-1:0] s4_data_i,
output reg s4_we_o,
output reg s4_rd_o,
input wire [`DATA_BUS_WIDTH-1:0] s5_data_i,
output reg s5_we_o,
output reg s5_rd_o,
input wire [`DATA_BUS_WIDTH-1:0] s6_data_i,
output reg s6_we_o,
output reg s6_rd_o
);
localparam SLAVE_0_ADDR = 4'b0000; // rom 0x0000_0000 ~ 0x0fff_ffff
localparam SLAVE_1_ADDR = 4'b0001; // ram 0x1000_0000 ~ 0x1fff_ffff
localparam SLAVE_2_ADDR = 4'b0010; // timer 0x2000_0000 ~ 0x2fff_ffff
localparam SLAVE_3_ADDR = 4'b0011; // uart 0x3000_0000 ~ 0x3fff_ffff
localparam SLAVE_4_ADDR = 4'b0100; // i2c 0x4000_0000 ~ 0x4fff_ffff
localparam SLAVE_5_ADDR = 4'b0101; // spi 0x5000_0000 ~ 0x5fff_ffff
localparam SLAVE_6_ADDR = 4'b0110; // lcd 0x6000_0000 ~ 0x6fff_ffff
always @ (*) begin
case (m_addr_i[31:28])
SLAVE_0_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s0_data_i[`DATA_BUS_WIDTH-1:0];
SLAVE_1_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s1_data_i[`DATA_BUS_WIDTH-1:0];
SLAVE_2_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s2_data_i[`DATA_BUS_WIDTH-1:0];
SLAVE_3_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s3_data_i[`DATA_BUS_WIDTH-1:0];
SLAVE_4_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s4_data_i[`DATA_BUS_WIDTH-1:0];
SLAVE_5_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s5_data_i[`DATA_BUS_WIDTH-1:0];
SLAVE_6_ADDR : m_data_o[`DATA_BUS_WIDTH-1:0] = s6_data_i[`DATA_BUS_WIDTH-1:0];
default : m_data_o[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
endcase
end
always @ (*) begin
s0_we_o = `INVALID;
s1_we_o = `INVALID;
s2_we_o = `INVALID;
s3_we_o = `INVALID;
s4_we_o = `INVALID;
s5_we_o = `INVALID;
s6_we_o = `INVALID;
case (m_addr_i[31:28])
SLAVE_0_ADDR : s0_we_o = m_we_i;
SLAVE_1_ADDR : s1_we_o = m_we_i;
SLAVE_2_ADDR : s2_we_o = m_we_i;
SLAVE_3_ADDR : s3_we_o = m_we_i;
SLAVE_4_ADDR : s4_we_o = m_we_i;
SLAVE_5_ADDR : s5_we_o = m_we_i;
SLAVE_6_ADDR : s6_we_o = m_we_i;
endcase
end
always @ (*) begin
s0_rd_o = `INVALID;
s1_rd_o = `INVALID;
s2_rd_o = `INVALID;
s3_rd_o = `INVALID;
s4_rd_o = `INVALID;
s5_rd_o = `INVALID;
s6_rd_o = `INVALID;
case (m_addr_i[31:28])
SLAVE_0_ADDR : s0_rd_o = m_rd_i;
SLAVE_1_ADDR : s1_rd_o = m_rd_i;
SLAVE_2_ADDR : s2_rd_o = m_rd_i;
SLAVE_3_ADDR : s3_rd_o = m_rd_i;
SLAVE_4_ADDR : s4_rd_o = m_rd_i;
SLAVE_5_ADDR : s5_rd_o = m_rd_i;
SLAVE_6_ADDR : s6_rd_o = m_rd_i;
endcase
end
endmodule

View File

@ -0,0 +1,153 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-06-05 Lyons first version
* 2023-06-13 Lyons add comments
*/
`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif
// dff, set 'def_val' when 'reset' is valid, update when 'enable' is valid
module pa_dff_rst_def #(
parameter DW = 32
)(
input wire clk_i,
input wire rst_n_i,
input wire [DW-1:0] def_val,
input wire en,
input wire [DW-1:0] din,
output wire [DW-1:0] qout
);
reg [DW-1:0] qout_r;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
qout_r[DW-1:0] <= def_val[DW-1:0];
end
else if (en) begin
qout_r[DW-1:0] <= din[DW-1:0];
end
else begin
qout_r[DW-1:0] <= qout_r[DW-1:0];
end
end
assign qout[DW-1:0] = qout_r[DW-1:0];
endmodule
// dff, set '0' when 'reset' is valid, update when 'enable' is valid
module pa_dff_rst_0 #(
parameter DW = 32
)(
input wire clk_i,
input wire rst_n_i,
input wire en,
input wire [DW-1:0] din,
output wire [DW-1:0] qout
);
pa_dff_rst_def #(DW) _dff (clk_i, rst_n_i, {DW{1'b0}}, en, din, qout);
endmodule
// dff, set '1' when 'reset' is valid, update when 'enable' is valid
module pa_dff_rst_1 #(
parameter DW = 32
)(
input wire clk_i,
input wire rst_n_i,
input wire en,
input wire [DW-1:0] din,
output wire [DW-1:0] qout
);
pa_dff_rst_def #(DW) _dff (clk_i, rst_n_i, {DW{1'b1}}, en, din, qout);
endmodule
// dff, update when 'enable' is valid, lock when it is invalid
module pa_dff_en_l #(
parameter DW = 32
)(
input wire clk_i,
input wire rst_n_i,
input wire en,
input wire [DW-1:0] din,
output wire [DW-1:0] qout
);
reg [DW-1:0] qout_r;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
qout_r[DW-1:0] <= 0;
end
else if (en) begin
qout_r[DW-1:0] <= din[DW-1:0];
end
else begin
qout_r[DW-1:0] <= qout_r[DW-1:0];
end
end
assign qout[DW-1:0] = qout_r[DW-1:0];
endmodule
// dff, update when 'enable' is valid
module pa_dff_en_2 #(
parameter DW = 32
)(
input wire clk_i,
input wire rst_n_i,
input wire en,
input wire [DW-1:0] din1,
input wire [DW-1:0] din2,
output wire [DW-1:0] qout
);
reg [DW-1:0] qout_r;
always @ (posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
qout_r[DW-1:0] <= 0;
end
else if (en) begin
qout_r[DW-1:0] <= din1[DW-1:0];
end
else begin
qout_r[DW-1:0] <= din2[DW-1:0];
end
end
assign qout[DW-1:0] = qout_r[DW-1:0];
endmodule

14
hardware/.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.SchDoc
!*.PcbDoc
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*

BIN
hardware/EasySoC.PcbDoc Normal file

Binary file not shown.

BIN
hardware/EasySoC.SchDoc Normal file

Binary file not shown.

13
scripts/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.exe
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*

BIN
scripts/bin2array.exe Normal file

Binary file not shown.

BIN
scripts/bin2mi.exe Normal file

Binary file not shown.

BIN
scripts/bin2packet.exe Normal file

Binary file not shown.

16
scripts/debugger/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.py
!*.ico
!*.bat
!*.exe
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*

Binary file not shown.

View File

@ -0,0 +1,486 @@
#coding=utf-8
# Name: debugger
# Date: 12:26 2024/1/8
# Note:
import os
import sys
import glob
import time
import msvcrt
import queue
import threading
import winreg
import win32api
import win32gui
from win32con import WM_INPUTLANGCHANGEREQUEST
import mysys
import myserial
import myconvert
## size of shell cmd buffer
SHELL_CMD_SIZE = 128
## size of download package
DOWNLOAD_PKG_SIZE = 64
## number of serial ports while scan
SERIAL_PORT_NUM = 30
## baudrate of serial port
SERIAL_BAUDRATE = 115200
## valid value of 'shell_stat'
STAT_WAIT_SPEC_KEY = 0
STAT_WAIT_FUNC_KEY = 1
## valid value of 'shell_mode'
MODE_MAX = 2
MODE_NORMAL = 0
MODE_CONTROL = 1
'''
debugger.py
'''
welcome_info = """This is a PuSH Terminal.
Type 'help' for more information.
"""
help_info = """Command:
----------------------------------------
~ - Switch mode.
quit - (q) Quit terminal.
repeat - (r) Repeat last command.
help - (h) Show help menu.
cd - Switch to work path.
load - (ld) Load file.
download - (d) Download to target device.
go - (g) Control target device jump and run.
com - Scan valid serial port.
com* - Open target serial port.
"""
example_info = """Example:
----------------------------------------
1. download & run
1) switch to control mode
2) ld > com > com* > [hardware reset] > [ESC] > d
2. go without download
1) switch to control mode
2) [hardware reset] > g
"""
class GlobalParam:
exitFlag = False
workPath = None
binFile = None
binData = None
binSize = 0
workQueue = None
queueLock = None
currentSerial = None
lastSerial = None
threadInput = None
threadOutput = None
def __init__(self):
self.workQueue = queue.Queue(SHELL_CMD_SIZE)
self.queueLock = threading.Lock()
def serial_check(self):
if self.currentSerial != None or self.lastSerial != None:
return True
else:
return False
def get_desktop_path(self):
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')
return winreg.QueryValueEx(key, 'Desktop')[0]
def get_work_path(self):
return r'..\..'
def cleanup(self):
while self.serial_check():
pass
class NewThread (threading.Thread):
def __init__(self, *args, **keywords):
threading.Thread.__init__(self, *args, **keywords)
self.killed = False
def start(self):
self.__run_backup = self.run
self.run = self.__run
threading.Thread.start(self)
def __run(self):
sys.settrace(self.globaltrace)
self.__run_backup()
self.run = self.__run_backup
def globaltrace(self, frame, event, arg):
if event == 'call':
return self.localtrace
else:
return None
def localtrace(self, frame, event, arg):
if self.killed:
if event == 'line':
raise SystemExit()
return self.localtrace
def kill(self):
self.killed = True
class Shell:
shell_trig = False
shell_mode = MODE_CONTROL
shell_stat = STAT_WAIT_SPEC_KEY
shell_line = None
shell_line_curpos = 0
def __init__(self, cmdsize):
self.shell_line = [0]*cmdsize
def output(self, ser, ch, redirect=True):
## handle control key
if self.shell_stat == STAT_WAIT_SPEC_KEY and ch == 0xe0:
self.shell_stat = STAT_WAIT_FUNC_KEY
return
elif self.shell_stat == STAT_WAIT_FUNC_KEY:
self.shell_stat = STAT_WAIT_SPEC_KEY
return
## handle tab key
if ch == ord('\t'):
return
## handle backspace key
elif ch == 0x08 or ch == 0x7f:
if self.shell_line_curpos == 0:
pass
else:
self.shell_line_curpos = self.shell_line_curpos - 1
self.shell_line[self.shell_line_curpos] = 0
_xputs(ser, "\b \b")
return
## handle enter key
elif ch == ord('\r'):
if redirect:
_xputs(ser, "\n")
return
## handle normal character
self.shell_line[self.shell_line_curpos] = ch
_xputs(ser, chr(ch))
## handle overwrite
self.shell_line_curpos = self.shell_line_curpos + 1
if self.shell_line_curpos >= SHELL_CMD_SIZE:
self.shell_line_curpos = 0
def _is_equal(v1, v2):
rslt = False
if type(v2) != type(list()):
rslt = mysys._is_equal(v1, v2)
else:
for v in v2:
if mysys._is_equal(v1, v):
rslt = True
break
return rslt
def _xputs(ser, info):
if ser == None:
mysys._xputs(info)
else:
for ch in info:
myserial.WriteData(ser, myconvert.ToHexStr([ord(ch),]))
def _tostr(data):
return "".join(chr(i) for i in data).lower()
def serial_thread(port):
global globalParam
ser = myserial.OpenPort(port, baud_rate=SERIAL_BAUDRATE)
globalParam.currentSerial = ser
globalParam.lastSerial = ser
shell = Shell(SHELL_CMD_SIZE)
try:
while not globalParam.exitFlag:
(state, length, data) = myserial.ReadData(ser)
if not state:
break
if length > 0:
for ch in data:
shell.output(None, ch, False)
else:
time.sleep(0.02)
finally:
myserial.ClosePort(ser)
globalParam.currentSerial = None
globalParam.lastSerial = None
def input_thread():
global globalParam
while not globalParam.exitFlag:
if msvcrt.kbhit():
globalParam.queueLock.acquire()
if not globalParam.workQueue.full():
globalParam.workQueue.put( msvcrt.getch() )
globalParam.queueLock.release()
time.sleep(0.02)
def output_thread():
global globalParam
## searh serial ports but not show them
serial_ports = myserial.SearchPort(SERIAL_PORT_NUM)
## only one serial thread is allowed to be created
tserial = None
## save the last command
last_cmd_line = "help"
## create shell and work on control mode
shell = Shell(SHELL_CMD_SIZE)
_xputs(None, ":")
while not globalParam.exitFlag:
## try to get one character
if not shell.shell_trig:
globalParam.queueLock.acquire()
ch = -1
if not globalParam.workQueue.empty():
ch = int.from_bytes(globalParam.workQueue.get(), byteorder='big')
globalParam.queueLock.release()
if ch < 0:
time.sleep(0.02)
continue
## handle esc key
if shell.shell_trig or ch == 0x1b:
shell.shell_trig = False
shell.shell_line_curpos = 0
shell.shell_mode = (shell.shell_mode + 1) % MODE_MAX
if shell.shell_mode == MODE_NORMAL:
_xputs(None, "enter normal mode ...\n")
if globalParam.serial_check():
_xputs(None, "serial port is alive.\n")
globalParam.currentSerial = globalParam.lastSerial
if shell.shell_mode == MODE_CONTROL:
_xputs(None, ":")
globalParam.currentSerial = None
continue
if shell.shell_mode == MODE_CONTROL:
if ch == ord('\r') or ch == ord('\n'):
cmd_line = _tostr(shell.shell_line[:shell.shell_line_curpos])
shell.shell_line_curpos = 0
## USER COMMAND PARSE AND EXECUTE BEGIN
if _is_equal(cmd_line, ['quit', 'q']):
_xputs(None, "\n")
if globalParam.serial_check():
tserial.kill()
tserial.join()
globalParam.exitFlag = True
continue
if _is_equal(cmd_line, ['repeat', 'r']):
_xputs(None, ":" + last_cmd_line)
cmd_line = last_cmd_line
last_cmd_line = cmd_line
_xputs(None, "\n")
if _is_equal(cmd_line, ['help', 'h']):
_xputs(None, help_info + "\n")
_xputs(None, example_info + "\n")
pass
if _is_equal(cmd_line.split(' ')[0], 'cd'):
globalParam.workPath = globalParam.get_desktop_path()
flist = glob.glob(globalParam.workPath + '\\*.bin')
_xputs(None, "work path: " + globalParam.workPath + "\n")
_xputs(None, "find {0} valid file: ".format(len(flist)) + "\n")
for file in flist:
_xputs(None, file.split('\\')[-1] + "\n")
_xputs(None, "\n")
pass
if _is_equal(cmd_line.split(' ')[0], ['load', 'ld']): ## 'load [xxx.bin]'
params = cmd_line.split(' ')
file = None
if len(params) > 1:
if len(params[1].split('.')) > 1:
file = params[1]
else:
file = params[1].split('.')[0] + '.bin'
else:
flist = glob.glob(globalParam.workPath + '\\*.bin')
if len(flist) > 0:
file = flist[0].split('\\')[-1]
if file != None:
_xputs(None, "open file: " + file + "\n")
try:
globalParam.binFile = globalParam.workPath + '\\' + file
with open(globalParam.binFile, 'rb') as fd:
globalParam.binData = fd.read()
globalParam.binSize = len(globalParam.binData)
_xputs(None, "read {0} bytes.".format(globalParam.binSize) + "\n")
except:
_xputs(None, "open failed." + "\n")
else:
_xputs(None, "invalid param." + "\n")
_xputs(None, "\n")
pass
if _is_equal(cmd_line.split(' ')[0], ['download', 'd']): ## 'download [com*]'
params = cmd_line.split(' ')
ser = None
if len(params) > 1:
ser = myserial.OpenPort(params[1], baud_rate=SERIAL_BAUDRATE)
needClose = True
else:
if globalParam.serial_check():
ser = globalParam.lastSerial
needClose = False
if globalParam.binSize > 0:
pkgs = 0
if ser != None:
bindata = globalParam.binData
while True:
pkgs = pkgs + 1
if len(bindata) >= DOWNLOAD_PKG_SIZE:
data = bindata[:DOWNLOAD_PKG_SIZE]
bindata = bindata[DOWNLOAD_PKG_SIZE:]
data = b'\xa5' + data + b'\x5a'
myserial.WriteData(ser, data)
_xputs(None, ".")
continue
else:
data = b'\xa5' + bindata + b'\x00'*(DOWNLOAD_PKG_SIZE-len(bindata)) + b'\x5a'
myserial.WriteData(ser, data)
_xputs(None, ".")
break
data = b'\xa6' + b'\x01' + b'\x00'*(DOWNLOAD_PKG_SIZE-1) + b'\x6a'
myserial.WriteData(ser, data)
_xputs(None, "." + "\n")
_xputs(None, "send {0} pkgs, pkg size {1}.".format(pkgs, DOWNLOAD_PKG_SIZE) + "\n")
if needClose:
myserial.ClosePort(ser)
shell.shell_trig = True
else:
_xputs(None, "invalid param." + "\n")
else:
_xputs(None, "please load bin file first." + "\n")
_xputs(None, "\n")
pass
if _is_equal(cmd_line.split(' ')[0], ['go', 'g']): ## 'go [com*]'
params = cmd_line.split(' ')
ser = None
if len(params) > 1:
ser = myserial.OpenPort(params[1], baud_rate=SERIAL_BAUDRATE)
needClose = True
else:
if globalParam.serial_check():
ser = globalParam.lastSerial
needClose = False
if ser != None:
data = b'\xa6' + b'\x02' + b'\x00'*(DOWNLOAD_PKG_SIZE-1) + b'\x6a'
myserial.WriteData(ser, data)
_xputs(None, "." + "\n")
_xputs(None, "send {0} pkgs, pkg size {1}.".format(1, DOWNLOAD_PKG_SIZE) + "\n")
if needClose:
myserial.ClosePort(ser)
shell.shell_trig = True
else:
_xputs(None, "invalid param." + "\n")
_xputs(None, "\n")
pass
if _is_equal(cmd_line, 'com'):
serial_ports = myserial.SearchPort(SERIAL_PORT_NUM)
_xputs(None, "valid port: " + str(serial_ports).replace('[','').replace(']','').replace('\'','') + "\n")
_xputs(None, "\n")
pass
if serial_ports != None: ## 'com*'
for i in range(len(serial_ports)):
if _is_equal(cmd_line, serial_ports[i]): # e.g. _is_equal(cmd_line, 'com20')
if globalParam.serial_check():
tserial.kill()
tserial.join()
tserial = NewThread(target=serial_thread, args=(serial_ports[i],))
tserial.start()
while not globalParam.serial_check():
pass
shell.shell_trig = True
pass
if shell.shell_trig:
continue
_xputs(None, ":")
## USER COMMAND PARSE AND EXECUTE END
continue
if shell.shell_mode == MODE_CONTROL or shell.shell_mode == MODE_NORMAL:
shell.output(globalParam.currentSerial, ch, True)
if __name__ == "__main__":
global globalParam
globalParam = GlobalParam()
mysys.env_init(lang='EN', cls=True, curs=False)
print(welcome_info, end="\n")
globalParam.workPath = globalParam.get_work_path()
globalParam.threadInput = NewThread(target=input_thread)
globalParam.threadOutput = NewThread(target=output_thread)
globalParam.threadInput.start()
globalParam.threadOutput.start()
globalParam.threadInput.join()
globalParam.threadOutput.join()
globalParam.cleanup()
timeout = 0
print("Exit After %d Second ..." % timeout, end="\n")
time.sleep(timeout)
mysys.env_init(lang='ZH', cls=False, curs=True)
print("Exit.", end="\n")

BIN
scripts/debugger/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,49 @@
#-*-coding: utf-8 -*-
def InsertBlock(hex_str):
if type(hex_str) != type("12"):
print("hex_str is not 'str' type!")
return None
else:
if len(hex_str)%2 != 0:
hex_str += '0'
print("add '0' at end,amended: ", end="")
print(hex_str)
hex_str_len = len(hex_str)
# print(hex_str_len)
hex_str_list = ["".join(hex_str[2*i:2*i+2]) for i in range(hex_str_len//2)]
# print(hex_str_list)
return " ".join(hex_str_list)
def ToHexStr(data):
if type(data) == type([1,]):
bytes_data = ToBytes(data)
return bytes_data.hex()
elif type(data) == type(b'\x00'):
return data.hex()
else:
print("only 'list' or 'bytes' is valid!")
return None
def ToIntList(data):
if type(data) == type('12'):
bytes_data = ToBytes(data)
return list(bytes_data)
elif type(data) == type(b'\x00'):
return list(data)
else:
print("only 'str' or 'bytes' is valid!")
return None
def ToBytes(data):
if type(data) == type('12'):
if len(data)%2 != 0:
data += '0'
print("add '0' at end,amended: ", end="")
print(data)
return bytes().fromhex(data)
elif type(data) == type([1,]):
return bytes(data)
else:
print("only 'str' or 'list' is valid!")
return None

View File

@ -0,0 +1,57 @@
#-*-coding: utf-8 -*-
import time
import serial
import myconvert
def SearchPort(num=20):
port_list = []
for idx in range(num):
name = 'COM' + str(idx)
try:
ser = serial.Serial(name)
ser.open
if ser.is_open:
port_list.append(name)
ser.close
except serial.serialutil.SerialException:
pass
return port_list
def OpenPort(port, baud_rate=9600, parity=serial.PARITY_NONE):
try:
ser = serial.Serial(port, baud_rate, parity=parity) # 8-data bits/1-stop bits
print("%s is opened, baudrate is %d." %(port, baud_rate), end="\n")
return ser
except:
return None
def ClosePort(ser):
try:
if ser.is_open:
print("%s is closed." %(ser.name), end="\n")
ser.close()
except:
pass
def ReadData(ser):
try:
if ser.is_open:
raw_data = ser.read(ser.in_waiting)
if len(raw_data) != 0:
return (True, len(raw_data), myconvert.ToIntList(raw_data))
else:
return (True, 0, None)
except:
return (False, 0, None)
def WriteData(ser, data):
try:
if ser.is_open:
if type(data) != type(b'\x00'):
data = myconvert.ToBytes(data)
ser.write(data)
time.sleep(1 / ser.baudrate * len(data) * 10)
except:
return None

70
scripts/debugger/mysys.py Normal file
View File

@ -0,0 +1,70 @@
#-*-coding: utf-8 -*-
import os
import sys
import win32api
import win32gui
from win32con import WM_INPUTLANGCHANGEREQUEST
def _is_equal(v1, v2):
## ignore case
if len(v1) != len(v2):
return 0
s1 = v1.lower()
s2 = v2.lower()
if s1 == s2:
return True
else:
return False
def _is_equal2(v1, v2):
## ignore case
if len(v1) != len(v1):
return 0
s1 = "".join(chr(i) for i in v1).lower()
s2 = v2.lower()
if s1 == s2:
return 1
else:
return 0
def _xputs(ch):
print(ch, end="")
sys.stdout.flush()
def change_language(lang="EN"):
LANG = {
"ZH": 0x0804,
"EN": 0x0409
}
hwnd = win32gui.GetForegroundWindow()
language = LANG[lang]
result = win32api.SendMessage(
hwnd,
WM_INPUTLANGCHANGEREQUEST,
0,
language
)
if not result:
return True
def env_init(lang="EN", cls=True, curs=True):
if curs:
os.system('echo -e "\033[?25h" 1>NUL')
else:
os.system('echo -e "\033[?25l"')
if cls:
os.system('cls')
change_language(lang)
if __name__ == "__main__":
env_init("EN", False)

View File

@ -0,0 +1,11 @@
@echo off
chcp 65001
rd build /S /Q
rd dist /S /Q
rd __pycache__ /S /Q
del *.spec /S
timeout /t 2

View File

@ -0,0 +1,15 @@
@echo off
chcp 65001
rd build /S /Q
rd dist /S /Q
rd __pycache__ /S /Q
del *.spec /S
del *.exe /S
pyinstaller -F -i icon.ico debugger.py
cp dist/*.exe .
timeout /t 2

19
sim/.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.mk
!Makefile
!*.lds
!*.h
!*.c
!*.s
!*.S
# Step-3, untrack all in sub folders, which use their own .gitignore
#*/*

91
sim/build.mk Normal file
View File

@ -0,0 +1,91 @@
#/*
# * Copyright {c} 2020-2021, SERI Development Team
# *
# * SPDX-License-Identifier: Apache-2.0
# *
# * Change Logs:
# * Date Author Notes
# * 2022-04-04 Lyons first version
# */
COLORS = "\033[32m"
COLORE = "\033[0m"
.PHONY: help
help:
@echo "help - help menu "
@echo "build - compile c/asm file "
@echo "compile - compile rtl file "
@echo "sim - simulate "
@echo "run - compile and simulate "
@echo "wave - open wave "
@echo "xemu - compile and run on xemu (linux platform) "
.PHONY: build
build:
@echo -e ${COLORS}[INFO] compile c/asm file ...${COLORE}
${Q}${CC} ${INCLUDES} ${INCFILES} ${CFLAGS} ${LDFLAGS} ${LDLIBS} ${ASMFILES} ${CFILES} -o ${TARGET}.elf
@echo -e ${COLORS}[INFO] create dump file ...${COLORE}
${Q}${OBJDUMP} -D -S ${TARGET}.elf > ${TARGET}.dump
@echo -e ${COLORS}[INFO] create image file ...${COLORE}
${Q}${OBJCOPY} -S -O binary ${TARGET}.elf ${TARGET}.bin
${Q}${OBJCOPY} -S -O verilog ${TARGET}.elf image.pat
ifneq ($(shell uname), Linux)
${Q}${PROJPATH}/scripts/bin2mi.exe ${TARGET}.bin
${Q}${CP} rom.mi ${PROJPATH}/riscv-bootloader.mi
endif
@echo -e ${COLORS}[INFO] execute done${COLORE}
.PHONY: compile
compile:
@echo -e ${COLORS}[INFO] compile design file ...${COLORE}
ifneq ($(shell uname), Linux)
${Q}${VCS} -g2012 -o wave.vvp ${ALLDEFINE} -f ${PROJPATH}/fpga_project/src//design.f ${TBFILES}
else
${Q}${VCS} -Mupdate -sverilog +v2k -debug_pp -timescale="1ns/100ps" ${ALLDEFINE} \
-f ${PROJPATH}/fpga_project/src//design.f ${TBFILES} \
-l compile.log
endif
@echo -e ${COLORS}[INFO] execute done${COLORE}
.PHONY: sim
sim:
@echo -e ${COLORS}[INFO] simulate ...${COLORE}
ifneq ($(shell uname), Linux)
${Q}${SIM} -n wave.vvp -lxt2
else
${Q}${SIM} -l sim.log
endif
@echo -e ${COLORS}[INFO] execute done${COLORE}
.PHONY: run
run: build compile sim
.PHONY: wave
wave:
@echo -e ${COLORS}[INFO] open wave ...${COLORE}
ifneq ($(shell uname), Linux)
${Q}${WAV} wave.vcd &
else
${Q}${WAV} -full64 -vpd wave.vpd &
endif
@echo -e ${COLORS}[INFO] execute done${COLORE}
.PHONY: xemu
xemu:
@echo -e ${COLORS}[INFO] compile xemu ...${COLORE}
${Q}make -C ${WORKPATH}/../xemu build
@echo -e ${COLORS}[INFO] simulate ...${COLORE}
ifneq ($(shell uname), Linux)
${Q}${WORKPATH}/../xemu/xemu.exe ${TARGET}.bin
else
${Q}${WORKPATH}/../xemu/xemu ${TARGET}.bin
endif
@echo -e ${COLORS}[INFO] execute done${COLORE}
.PHONY: clean
clean:
@echo -e ${COLORS}[INFO] clean project ...${COLORE}
@make -C ${WORKPATH}/../xemu clean
@ls | grep -vE "Makefile|driver|rtthread-nano|*\.lds$$|*\.c$$|*\.h$$" | xargs -i rm -rf {}
@echo -e ${COLORS}[INFO] execute done${COLORE}

86
sim/config.mk Normal file
View File

@ -0,0 +1,86 @@
#/*
# * Copyright {c} 2020-2021, SERI Development Team
# *
# * SPDX-License-Identifier: Apache-2.0
# *
# * Change Logs:
# * Date Author Notes
# * 2022-04-04 Lyons first version
# */
# Note:
# 1. if work on Windows, you can use iverilog, Gowin FPGA or XEMU to simulate
# 2. if work on Linux, you can use VCS or XEMU to simulate
ifeq ($(shell uname), Linux)
EMBTOOLPATH = /home/crazy/Tools/compiler/xuantie/v8.4.0/riscv64-elf-x86_64-20210307
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc
OBJDUMP = ${EMBTOOLPREFIX}-objdump
OBJCOPY = ${EMBTOOLPREFIX}-objcopy
else
EMBTOOLPATH = D:/EmbedCompiler/riscv64-elf-mingw-20210306
EMBTOOLPREFIX = ${EMBTOOLPATH}/bin/riscv64-unknown-elf
CC = ${EMBTOOLPREFIX}-gcc.exe
OBJDUMP = ${EMBTOOLPREFIX}-objdump.exe
OBJCOPY = ${EMBTOOLPREFIX}-objcopy.exe
endif
ifeq ($(shell uname), Linux)
VCS = vcs
SIM = ./simv
WAV = dve
else
VCS = D:/iverilog/bin/iverilog.exe
SIM = D:/iverilog/bin/vvp.exe
WAV = D:/iverilog/gtkwave/bin/gtkwave.exe
endif
RM = rm -f
CP = cp
MV = mv
# for vcs tools
ifeq ($(shell uname), Linux)
ALLDEFINE = +define+DUMP_VPD
ALLDEFINE += +define+TESTBENCH_VCS
else
ALLDEFINE = -DDUMP_VCD
ALLDEFINE += -DTESTBENCH_VCS
endif
TBFILES = ${PROJPATH}/tb/prim_sim.v \
${PROJPATH}/fpga_project/src/ipdefs/gowin_rpll/gowin_rpll.v \
${PROJPATH}/fpga_project/src/ipdefs/gowin_dpb_8x4k/gowin_dpb_8x4k.v \
${PROJPATH}/fpga_project/src/ipdefs/gowin_dpb_32x8k/gowin_dpb_32x8k.v \
${PROJPATH}/tb/core_data_monitor_tb.v \
${PROJPATH}/tb/core_uart_monitor_tb.v \
${PROJPATH}/tb/core_tb.v
# for c/asm tools
INCLUDES =
INCFILES = -I${PROJPATH}/sim/libs \
-I${PROJPATH}/sim/libs/_sdk \
-I${PROJPATH}/sim/libs/_sdk/systick \
-I${PROJPATH}/sim/libs/_sdk/gpio \
-I${PROJPATH}/sim/libs/_sdk/timer \
-I${PROJPATH}/sim/libs/_sdk/uart \
-I${PROJPATH}/sim/libs/_utilities
CFLAGS = -march=rv32im -mabi=ilp32 -mcmodel=medlow
LDFLAGS = -Wl,-Map,${TARGET}.map,-warn-common \
-Wl,--gc-sections \
-Wl,--no-relax \
-nostartfiles
LDLIBS = -lm -lc -lgcc
ASMFILES = ${PROJPATH}/sim/libs/_startup/start.S \
${PROJPATH}/sim/libs/_startup/trap.S
CFILES = ${PROJPATH}/sim/libs/_sdk/systick/*.c \
${PROJPATH}/sim/libs/_sdk/timer/*.c \
${PROJPATH}/sim/libs/_sdk/uart/*.c \
${PROJPATH}/sim/libs/_utilities/*.c

68
sim/libs/_sdk/__def.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#ifndef __DEF_H__
#define __DEF_H__
#include <stdint.h>
#define CPU_FREQ_HZ (10125000)
#define CPU_FREQ_KHZ (CPU_FREQ_HZ / 1000)
#define CPU_FREQ_MHZ (CPU_FREQ_HZ / 1000000)
#define LCD_X_SIZE (240)
#define LCD_Y_SIZE (135)
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
#ifndef UNUSED
#define UNUSED(X) ((void)X)
#endif
#define CLEAR_ARRAY(ins,data) memset((uint8_t*)ins,data,sizeof(ins))
#define CLEAR_STRUCT(ins,data) memset((uint8_t*)ins,data,sizeof(ins))
#define GET_ARRAY_NUM(ins) ((uint32_t)(sizeof(ins)/sizeof(ins[0])))
#define GET_STRUCT_SIZE(ins) ((uint32_t)(sizeof(ins)))
#define GET_WORD_BYTE0(w) ((uint8_t)((w) & 0xFF))
#define GET_WORD_BYTE1(w) ((uint8_t)((w>>8) & 0xFF))
#define GET_DWORD_BYTE0(d) GET_WORD_BYTE0(d)
#define GET_DWORD_BYTE1(d) GET_WORD_BYTE1(d)
#define GET_DWORD_BYTE2(d) ((uint8_t)(((d)>>16) & 0xFF))
#define GET_DWORD_BYTE3(d) ((uint8_t)(((d)>>24) & 0xFF))
#define BUILD_WORD(a,b) ((uint16_t)(((a)<<8 ) | (b)))
#define BUILD_DWORD(a,b,c,d) ((uint32_t)(((a)<<24) | ((b)<<16) | ((c)<<8) | (d)))
#define _internal_ro static const
#define _internal_rw static
#define _internal_zi static
#define read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define write_csr(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
#include "__simulation.h"
#endif //#ifndef __DEF_H__

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#ifndef __SIMULATION_H__
#define __SIMULATION_H__
#include "uart.h"
#define _csr_putc(val) write_csr(mscratchcswl, val)
#define _uart_putc(val) uart_send_wait(UART1, val)
#ifdef PRINT_STDIO_SIM
#define simulation(data) \
do { \
_csr_putc( (1<<31)|0x1b ); _csr_putc(0); \
_csr_putc( (1<<31)|data ); _csr_putc(0); \
} while (0);
#else
#define simulation(data) \
do { \
_uart_putc(0x1b); \
_uart_putc(data); \
} while (0);
#endif // #ifdef PRINT_STDIO_SIM
#endif //#ifndef __SIMULATION_H__

51
sim/libs/_sdk/gpio/gpio.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-12-23 Lyons first version
*/
#ifndef __GPIO_H__
#define __GPIO_H__
#include "__def.h"
typedef struct
{
__IO uint32_t cr;
__IO uint32_t in;
__IO uint32_t out;
uint32_t rsvd;
__O uint32_t obit[16];
} GPIO_Type;
#define GPIO_BASE (0x40000000)
#define GPIO1 ((GPIO_Type*)(GPIO_BASE))
#define POut(n,v) do { \
GPIO1->obit[n] = v; \
} while (0);
#define LCD_BK_OFF POut(3,0)
#define LCD_BK_ON POut(3,1)
#define LCD_CS0_EN POut(5,0)
#define LCD_CS0_DIS POut(5,1)
#define LCD_RST_L POut(7,0)
#define LCD_RST_H POut(7,1)
#define LCD_DC_L POut(8,0)
#define LCD_DC_H POut(8,1)
#define LCD_SCL_L POut(9,0)
#define LCD_SCL_H POut(9,1)
#define LCD_SDA_L POut(11,0)
#define LCD_SDA_H POut(11,1)
#endif //#ifndef __UART_H__

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-08 Lyons first version
*/
#include "systick.h"
uint64_t get_cycle_value(void)
{
uint64_t cycle;
cycle = read_csr(cycle);
cycle += (uint64_t)(read_csr(cycleh)) << 32;
return cycle;
}
uint32_t get_cyclel_value(void)
{
return read_csr(cycle);
}
void delay_us(uint32_t us)
{
uint64_t start;
uint64_t end;
if (0 == us) {
return;
}
start = get_cycle_value();
end = start + (us * CPU_FREQ_KHZ) / 1000;
while (get_cycle_value() < end);
}
void delay_ms(uint32_t ms)
{
if (0 == ms) {
return;
}
while (ms--) {
delay_us(1000);
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-08 Lyons first version
*/
#ifndef __SYSTICK_H__
#define __SYSTICK_H__
#include "__def.h"
uint64_t get_cycle_value(void);
uint32_t get_cyclel_value(void);
void delay_us();
void delay_ms();
#endif //#ifndef __SYSTICK_H__

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#include "timer.h"
void timer_init(TIM_Type *tim, uint32_t psc, uint32_t value)
{
tim->cr &= ~TIM_CR_EN; //close first
tim->sr |= TIM_SR_CLR_TUF;
tim->psc = (0 == psc) ? 0 : (psc-1);
tim->load = value;
}
void timer_control(TIM_Type *tim, uint8_t en)
{
uint32_t dummy;
dummy = tim->cr;
if (TIM_EN == en)
{
dummy |= TIM_CR_EN;
} else {
dummy &= ~TIM_CR_EN;
}
tim->cr = dummy;
}
void timer_clearflag(TIM_Type *tim, uint32_t flag)
{
tim->sr = flag;
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#include "__def.h"
typedef struct
{
__IO uint32_t cr;
__IO uint32_t sr;
__IO uint32_t psc;
__O uint32_t load;
__I uint32_t count;
} TIM_Type;
#define TIM_BASE (0x20000000)
#define TIM1 ((TIM_Type*)(TIM_BASE))
// [0]: enbale
#define TIM_CR_EN (uint32_t)(1 << 0)
// [0]: timing-up flag
#define TIM_SR_FLAG_TUF (uint32_t)(1 << 0)
#define TIM_SR_CLR_TUF (uint32_t)(1 << 0) //write "1" clear
#define TIM_EN (uint8_t)0x1
#define TIM_DIS (uint8_t)0x0
void timer_init(TIM_Type *tim, uint32_t psc, uint32_t value);
void timer_control(TIM_Type *tim, uint8_t en);
void timer_clearflag(TIM_Type *tim, uint32_t flag);
#endif //#ifndef __TIMER_H__

51
sim/libs/_sdk/uart/uart.c Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#include "uart.h"
void uart_send(UART_Type *uart, uint8_t data)
{
uart->sr = UART_SR_CLR_TXE;
uart->txd = data;
}
void uart_send_wait(UART_Type *uart, uint8_t data)
{
uart->txd = data;
while ( !(uart->sr & UART_SR_FLAG_TXE) );
uart->sr = UART_SR_CLR_TXE;
}
uint8_t uart_read(UART_Type *uart)
{
uint8_t dummy;
if (uart->sr & UART_SR_FLAG_RXNE)
{
dummy = uart->rxd;
uart->sr = UART_SR_CLR_RXNE;
} else {
dummy = 0xFF; //0xFF is -1
}
return dummy;
}
uint8_t uart_read_wait(UART_Type *uart)
{
uint8_t dummy;
while ( !(uart->sr & UART_SR_FLAG_RXNE) );
dummy = uart->rxd;
uart->sr = UART_SR_CLR_RXNE;
return dummy;
}

50
sim/libs/_sdk/uart/uart.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#ifndef __UART_H__
#define __UART_H__
#include "__def.h"
typedef struct
{
__IO uint32_t cr;
__IO uint32_t sr;
__I uint32_t baud;
__I uint32_t rxd;
__IO uint32_t txd;
} UART_Type;
#define UART_BASE (0x30000000)
#define UART1 ((UART_Type*)(UART_BASE))
#define UART2 ((UART_Type*)(UART_BASE + 0x10000000))
#define UART3 ((UART_Type*)(UART_BASE + 0x20000000))
// [0]: tx enbale
// [1]: rx enbale
#define UART_CR_TX_EN (uint32_t)(1 << 0)
#define UART_CR_RX_EN (uint32_t)(1 << 1)
// [0]: tx flag
// [1]: rx flag
#define UART_SR_FLAG_TXE (uint32_t)(1 << 0)
#define UART_SR_FLAG_RXNE (uint32_t)(1 << 1)
#define UART_SR_CLR_TXE (uint32_t)(1 << 0) //write "1" clear
#define UART_SR_CLR_RXNE (uint32_t)(1 << 1)
void uart_send(UART_Type *uart, uint8_t data);
void uart_send_wait(UART_Type *uart, uint8_t data);
uint8_t uart_read(UART_Type *uart);
uint8_t uart_read_wait(UART_Type *uart);
#endif //#ifndef __UART_H__

56
sim/libs/_startup/start.S Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
.section .init
.globl _start
.type _start,@function
_start:
.option push
.option pop
la gp, __stack_top
addi sp, gp, -1024
la a0, __bss_start
la a1, __bss_end
bgeu a0, a1, _bss_init_end
_bss_init_begin:
sw zero, 0(a0)
addi a0, a0, 4
bltu a0, a1, _bss_init_begin
_bss_init_end:
la a0, __data_lma
la a1, __data_start
la a2, __data_end
bgeu a1, a2, _data_init_end
_data_init_begin:
lw t0, 0(a0)
sw t0, 0(a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, _data_init_begin
_data_init_end:
call init
call entry
loop:
j loop
.weak init
init:
ret
.weak entry
entry:
call main
ret

179
sim/libs/_startup/trap.S Normal file
View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
.section .text
.global interrupt_enable
.align 2
interrupt_disable:
csrrci a0, mstatus, 8
ret
.global interrupt_disable
.align 2
interrupt_enable:
csrw mstatus, a0
ret
/* Macro for saving task context */
.macro save_context
addi sp, sp, -32*4
sw x1, 1*4(sp)
csrr x1, mepc
sw x1, 0*4(sp)
li x1, 0x0088
sw x1, 2*4(sp)
sw x4, 4*4(sp)
sw x5, 5*4(sp)
sw x6, 6*4(sp)
sw x7, 7*4(sp)
sw x8, 8*4(sp)
sw x9, 9*4(sp)
sw x10, 10*4(sp)
sw x11, 11*4(sp)
sw x12, 12*4(sp)
sw x13, 13*4(sp)
sw x14, 14*4(sp)
sw x15, 15*4(sp)
sw x16, 16*4(sp)
sw x17, 17*4(sp)
sw x18, 18*4(sp)
sw x19, 19*4(sp)
sw x20, 20*4(sp)
sw x21, 21*4(sp)
sw x22, 22*4(sp)
sw x23, 23*4(sp)
sw x24, 24*4(sp)
sw x25, 25*4(sp)
sw x26, 26*4(sp)
sw x27, 27*4(sp)
sw x28, 28*4(sp)
sw x29, 29*4(sp)
sw x30, 30*4(sp)
sw x31, 31*4(sp)
.endm
/* Macro for restoring task context */
.macro restore_context
lw x1, 0*4(sp)
csrw mepc, x1
lw x1, 1*4(sp)
li t0, 0x1800
csrw mstatus, t0
lw t0, 2*4(sp)
csrs mstatus, t0
lw x4, 4*4(sp)
lw x5, 5*4(sp)
lw x6, 6*4(sp)
lw x7, 7*4(sp)
lw x8, 8*4(sp)
lw x9, 9*4(sp)
lw x10, 10*4(sp)
lw x11, 11*4(sp)
lw x12, 12*4(sp)
lw x13, 13*4(sp)
lw x14, 14*4(sp)
lw x15, 15*4(sp)
lw x16, 16*4(sp)
lw x17, 17*4(sp)
lw x18, 18*4(sp)
lw x19, 19*4(sp)
lw x20, 20*4(sp)
lw x21, 21*4(sp)
lw x22, 22*4(sp)
lw x23, 23*4(sp)
lw x24, 24*4(sp)
lw x25, 25*4(sp)
lw x26, 26*4(sp)
lw x27, 27*4(sp)
lw x28, 28*4(sp)
lw x29, 29*4(sp)
lw x30, 30*4(sp)
lw x31, 31*4(sp)
addi sp, sp, 32*4
.endm
.global trap_entry
.align 2
trap_entry:
j vector_handler
vector_handler:
_save:
save_context
#ifdef OS_ENABLE_RT_THREAD
la t0, rt_interrupt_nest
li t1, 1
sb t1, 0(t0)
#endif
csrr a0, mcause
csrr a1, mepc
srli t0, a0, 31
beq t0, a0, _is_exception
csrw mscratch, sp
mv sp, gp
call trap_handler
csrr sp, mscratch
j _is_interrupt
_is_exception:
addi a1, a1, 4
csrw mepc, a1
_is_interrupt:
#ifdef OS_ENABLE_RT_THREAD
la s0, rt_thread_switch_interrupt_flag
lw s2, 0(s0)
beqz s2, _restore
sw zero, 0(s0)
la s0, rt_interrupt_from_thread
lw s1, 0(s0)
sw sp, 0(s1)
la s0, rt_interrupt_to_thread
lw s1, 0(s0)
lw sp, 0(s1)
#endif
_restore:
#ifdef OS_ENABLE_RT_THREAD
la t0, rt_interrupt_nest
sb zero, 0(t0)
#endif
restore_context
mret
_nop_list:
nop
nop
nop
.weak trap_handler
trap_handler:
ret

View File

@ -0,0 +1,165 @@
/*------------------------------------------------------------------------/
/ Universal string handler for user console interface
/-------------------------------------------------------------------------/
/
/ Copyright (C) 2011, ChaN, all right reserved.
/
/ * This software is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/-------------------------------------------------------------------------*/
#include <stdarg.h>
#include "__def.h"
#include "uart.h"
#include "xprintf.h"
/*----------------------------------------------*/
/* Put a character */
/*----------------------------------------------*/
void xputc (char c)
{
if ('\n' == c)
{
#ifdef PRINT_STDIO_SIM
_csr_putc( (1<<31)|(uint8_t)'\r' ); _csr_putc(0);
#else
_uart_putc( (uint8_t)'\r' );
#endif
}
#ifdef PRINT_STDIO_SIM
_csr_putc( (1<<31)|(uint8_t)c ); _csr_putc(0);
#else
_uart_putc( (uint8_t)c );
#endif
}
/*----------------------------------------------*/
/* Put a null-terminated string */
/*----------------------------------------------*/
void xputs ( /* Put a string to the default device */
const char* str /* Pointer to the string */
)
{
while (*str)
xputc(*str++);
}
/*----------------------------------------------*/
/* Formatted string output */
/*----------------------------------------------*/
/* xprintf("%d", 1234); "1234"
xprintf("%6d,%3d%%", -200, 5); " -200, 5%"
xprintf("%-6u", 100); "100 "
xprintf("%ld", 12345678L); "12345678"
xprintf("%04x", 0xA3); "00a3"
xprintf("%08LX", 0x123ABC); "00123ABC"
xprintf("%016b", 0x550F); "0101010100001111"
xprintf("%s", "String"); "String"
xprintf("%-4s", "abc"); "abc "
xprintf("%4s", "abc"); " abc"
xprintf("%c", 'a'); "a"
xprintf("%f", 10.0); <xprintf lacks floating point support>
*/
static
void xvprintf (
const char* fmt, /* Pointer to the format string */
va_list arp /* Pointer to arguments */
)
{
unsigned int r, i, j, w, f;
unsigned long v;
char s[16], c, d, *p;
for (;;) {
c = *fmt++; /* Get a char */
if (!c) break; /* End of format? */
if (c != '%') { /* Pass through it if not a % sequense */
xputc(c); continue;
}
f = 0;
c = *fmt++; /* Get first char of the sequense */
if (c == '0') { /* Flag: '0' padded */
f = 1; c = *fmt++;
} else {
if (c == '-') { /* Flag: left justified */
f = 2; c = *fmt++;
}
}
for (w = 0; c >= '0' && c <= '9'; c = *fmt++) /* Minimum width */
w = w * 10 + c - '0';
if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
f |= 4; c = *fmt++;
}
if (!c) break; /* End of format? */
d = c;
if (d >= 'a') d -= 0x20;
switch (d) { /* Type is... */
case 'S' : /* String */
p = va_arg(arp, char*);
for (j = 0; p[j]; j++) ;
while (!(f & 2) && j++ < w) xputc(' ');
xputs(p);
while (j++ < w) xputc(' ');
continue;
case 'C' : /* Character */
xputc((char)va_arg(arp, int)); continue;
case 'B' : /* Binary */
r = 2; break;
case 'O' : /* Octal */
r = 8; break;
case 'D' : /* Signed decimal */
case 'U' : /* Unsigned decimal */
r = 10; break;
case 'X' : /* Hexdecimal */
r = 16; break;
default: /* Unknown type (passthrough) */
xputc(c); continue;
}
/* Get an argument and put it in numeral */
v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int));
if (d == 'D' && (v & 0x80000000)) {
v = 0 - v;
f |= 8;
}
i = 0;
do {
if (2 == r) {d = (char)(v & 0x00000001); v >>= 1;}
else if (8 == r) {d = (char)(v & 0x00000007); v >>= 3;}
else if (10 == r) {d = (char)(v % r); v /= r;}
else if (16 == r) {d = (char)(v & 0x0000000f); v >>= 4;}
else {d = 0; v = 0;}
if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
s[i++] = d + '0';
} while (v && i < sizeof(s));
if (f & 8) s[i++] = '-';
j = i; d = (f & 1) ? '0' : ' ';
while (!(f & 2) && j++ < w) xputc(d);
do xputc(s[--i]); while(i);
while (j++ < w) xputc(' ');
}
}
void xprintf ( /* Put a formatted string to the default device */
const char* fmt, /* Pointer to the format string */
... /* Optional arguments */
)
{
va_list arp;
va_start(arp, fmt);
xvprintf(fmt, arp);
va_end(arp);
}

View File

@ -0,0 +1,21 @@
/*------------------------------------------------------------------------/
/ Universal string handler for user console interface
/-------------------------------------------------------------------------/
/
/ Copyright (C) 2011, ChaN, all right reserved.
/
/ * This software is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/-------------------------------------------------------------------------*/
#ifndef _XPRINTF_H_
#define _XPRINTF_H_
void xputc (char c);
void xputs (const char* str);
void xprintf (const char* fmt, ...);
#endif

22
sim/simple/.gitignore vendored Normal file
View File

@ -0,0 +1,22 @@
#.gitignore
# Step-1, track all files in the current folder
!*
# Step-2, track specified files in the current folder
*
!*/
!.gitignore
!*.mk
!Makefile
!*.lds
!*.h
!*.c
!*.s
!*.S
# Step-3, untrack all in sub folders, which use their own .gitignore
*/*
!driver/*
!rtthread-nano/*

74
sim/simple/Makefile Normal file
View File

@ -0,0 +1,74 @@
#/*
# * Copyright {c} 2020-2021, SERI Development Team
# *
# * SPDX-License-Identifier: Apache-2.0
# *
# * Change Logs:
# * Date Author Notes
# * 2022-03-27 Lyons first version
# */
TARGET = riscv
Q = @
PROJPATH = ../..
WORKPATH = .
include ../config.mk
INCLUDES += -I.
INCFILES += -I${WORKPATH}/rtthread-nano/bsp \
-I${WORKPATH}/rtthread-nano/components/finsh \
-I${WORKPATH}/rtthread-nano/include \
-I${WORKPATH}/rtthread-nano/include/libc \
-I${WORKPATH}/libs/_kernel/libcpu/risc-v/common
INCFILES += -I${WORKPATH}/driver
CFLAGS += -O0 -ffunction-sections -fdata-sections
# CFLAGS += -g
CFLAGS += -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
CFLAGS += -DOS_ENABLE_RT_THREAD
# CFLAGS += -DPRINT_STDIO_SIM
CFLAGS += -DSIMULATION_PRINT_VERSION
# CFLAGS += -DSIMULATION_PRINT_THREAD_SWITCH
LDFLAGS += -T${WORKPATH}/link.lds
LDLIBS +=
ASMFILES += ${WORKPATH}/rtthread-nano/libcpu/risc-v/common/context_gcc.S
CFILES += ${WORKPATH}/rtthread-nano/bsp/board.c \
${WORKPATH}/rtthread-nano/components/device/device.c \
${WORKPATH}/rtthread-nano/components/finsh/cmd.c \
${WORKPATH}/rtthread-nano/components/finsh/finsh_port.c \
${WORKPATH}/rtthread-nano/components/finsh/msh.c \
${WORKPATH}/rtthread-nano/components/finsh/shell.c \
${WORKPATH}/rtthread-nano/libcpu/risc-v/common/cpuport.c \
${WORKPATH}/rtthread-nano/src/clock.c \
${WORKPATH}/rtthread-nano/src/components.c \
${WORKPATH}/rtthread-nano/src/cpu.c \
${WORKPATH}/rtthread-nano/src/idle.c \
${WORKPATH}/rtthread-nano/src/ipc.c \
${WORKPATH}/rtthread-nano/src/irq.c \
${WORKPATH}/rtthread-nano/src/kservice.c \
${WORKPATH}/rtthread-nano/src/mem.c \
${WORKPATH}/rtthread-nano/src/memheap.c \
${WORKPATH}/rtthread-nano/src/mempool.c \
${WORKPATH}/rtthread-nano/src/object.c \
${WORKPATH}/rtthread-nano/src/scheduler.c \
${WORKPATH}/rtthread-nano/src/slab.c \
${WORKPATH}/rtthread-nano/src/thread.c \
${WORKPATH}/rtthread-nano/src/timer.c
CFILES += ${WORKPATH}/driver/Driver_tftspi.c \
${WORKPATH}/driver/Task_tft.c
CFILES += ${WORKPATH}/init.c \
${WORKPATH}/interrupt.c \
${WORKPATH}/main.c
include ../build.mk

View File

@ -0,0 +1,629 @@
/**
******************************************************************************
*
* TFT 1.14使SPI
*
*
*
* 2022-12-07 v1.0
*
* Create 20160909
* Update 20221207
* Author dengchow
*
******************************************************************************
***/
#include "Driver_tftspi.h"
#define LCD_MODE 2
// 0 // 竖屏
// 1
// 2 // 横屏
// 3
uint16_t POINT_COLOR = 0x0000;//画笔颜色
uint16_t BACK_COLOR = 0xFFFF;//背景色
_TFTCmdTypeStruct TFTCmd;//管理LCD重要参数
/**
* @brief :SPI发送数据
* @note :--
* @param :dat
* @return :void
*
* @data :2023/01/21
* @design :
**/
static void _spi_write_data(uint8_t dat)
{
#ifdef LCD_SPI_SOFT
for (uint8_t i=0; i<8; i++)
{
LCD_SCL_L;
if (dat & 0x80) {
LCD_SDA_H;
} else {
LCD_SDA_L;
}
LCD_SCL_H;
dat <<= 1;
}
#endif
}
/**
* @brief :
* @note :--
* @param :reg,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WR_REG(uint16_t reg)
{
TFT_DC_CMD();
_spi_write_data(reg);
TFT_DC_DATA();
}
/**
* @brief :
* @note :--使TFT_WR_REG()
* @param :dat,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WR_DATA8(uint8_t dat)
{
_spi_write_data(dat);
}
void TFT_WR_DATA(uint16_t dat)
{
_spi_write_data(dat>>8);
_spi_write_data(dat);
}
/**
* @brief :
* @note :--
* @param :void
* @return :uint16_t,
*
* @data :2017/03/04
* @design :
**/
uint16_t TFT_RD_DATA(void)
{
return BACK_COLOR; // NO USED!
}
/**
* @brief :lcd设备
* @note :--
* @param :idx, lcd序号
en, 1/0
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_Select(uint8_t idx, uint8_t en)
{
if (0 == en)
{
switch (idx)
{
case 0: LCD_CS0_DIS; break;
default: {
LCD_CS0_DIS;
break;
}
}
} else {
switch (idx)
{
case 0: LCD_CS0_EN; break;
default: {
LCD_CS0_EN;
break;
}
}
}
}
/**
* @brief :
* @note :--
* @param :reg,
dat,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WriteReg(uint16_t reg, uint16_t dat)
{
TFT_WR_REG(reg);
TFT_WR_DATA(dat);
}
/**
* @brief :
* @note :--
* @param :Reg,
* @return :uint16_t,
*
* @data :2017/03/04
* @design :
**/
uint16_t TFT_ReadReg(uint16_t reg)
{
return 0xFFFF; // NO USED!
}
/**
* @brief :GRAM
* @note :--
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_StartWriteRAM(void)
{
TFT_WR_REG(0x2C);
}
/**
* @brief :GRAM
* @note :--
* @param :color,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_WriteRAM(uint16_t color)
{
TFT_WR_DATA(color);
}
/**
* @brief :tft开启显示
* @note :
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_DisplayOn(void)
{
// NO USED!
}
/**
* @brief :tft关闭显示
* @note :--
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_DisplayOff(void)
{
// NO USED!
}
/**
* @brief :
* @note :--
* @param :X1, (0~TFTCmd.width)
Y1, (0~TFTCmd.height)
X2, (0~TFTCmd.width)
Y3, (0~TFTCmd.height)
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_SetCursor(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2)
{
#if (LCD_MODE == 0)
const uint16_t _k_x_base = 52;
const uint16_t _k_y_base = 40;
#endif
#if (LCD_MODE == 1)
const uint16_t _k_x_base = 53;
const uint16_t _k_y_base = 40;
#endif
#if (LCD_MODE == 2)
const uint16_t _k_x_base = 40;
const uint16_t _k_y_base = 53;
#endif
#if (LCD_MODE == 3)
const uint16_t _k_x_base = 40;
const uint16_t _k_y_base = 52;
#endif
TFT_WR_REG(0x2A); //列地址设置
TFT_WR_DATA(X1+_k_x_base);
TFT_WR_DATA(X2+_k_x_base);
TFT_WR_REG(0x2B); //行地址设置
TFT_WR_DATA(Y1+_k_y_base);
TFT_WR_DATA(Y2+_k_y_base);
}
/**
* @brief :tft的自动扫描方向
* @note :--ILI9341的其他函数可能会受到此函数设置的影响L2R_U2D
--ILI9341进行修改bug
--ILI9341默认为RGB格式
* @param :direct, (_TFTScanDir枚举类型中定义)
* @return :void
*
* @data :2018/01/24
* @design :
**/
void TFT_SetScanDir(_TFTScanDir direct)
{
// NO USED!
}
/**
* @brief :tft显示方向
* @note :--
* @param :direct, (_TFTDispDir枚举类型定义)
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_SetDisplayDir(_TFTDispDir direct)
{
if(direct == DISP_PORTRAIT)//竖屏
{
TFTCmd.dir = DISP_PORTRAIT;
TFTCmd.width = CFG_LCD_Y_SIZE;
TFTCmd.height = CFG_LCD_X_SIZE;
}else{//横屏
TFTCmd.dir = DISP_HORIZON;
TFTCmd.width = CFG_LCD_X_SIZE;
TFTCmd.height = CFG_LCD_Y_SIZE;
}
TFTCmd.wramcmd = 0; // NO USED!
TFTCmd.setxcmd = 0; // NO USED!
TFTCmd.setycmd = 0; // NO USED!
}
/**
* @brief :tft窗口大小
* @note :--width*height
* @param :XS ,
YS ,
width , ,0!
height, ,0!
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_SetWindowSize(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height)
{
// NO USED!
}
/**
* @brief :tft初始化设置
* @note :--
* @param :void
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_InitConfig(void)
{
TFT_BACK_LED_CLOSE();
TFT_Select(0xff, 1); // SELECT ALL DEVICE!
TFT_RST_HIGH();
delay_ms(1);
TFT_RST_LOW();
delay_ms(10);
TFT_RST_HIGH();
delay_ms(120);
TFT_WR_REG(0x36);
#if (LCD_MODE == 0)
TFT_WR_DATA8(0x00);
#endif
#if (LCD_MODE == 1)
TFT_WR_DATA8(0xC0);
#endif
#if (LCD_MODE == 2)
TFT_WR_DATA8(0x70);
#endif
#if (LCD_MODE == 3)
TFT_WR_DATA8(0xA0);
#endif
TFT_WR_REG(0x3A);
TFT_WR_DATA8(0x05);
TFT_WR_REG(0xB2);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x00);
TFT_WR_DATA8(0x33);
TFT_WR_DATA8(0x33);
TFT_WR_REG(0xB7);
TFT_WR_DATA8(0x35);
TFT_WR_REG(0xBB);
TFT_WR_DATA8(0x19);
TFT_WR_REG(0xC0);
TFT_WR_DATA8(0x2C);
TFT_WR_REG(0xC2);
TFT_WR_DATA8(0x01);
TFT_WR_REG(0xC3);
TFT_WR_DATA8(0x12);
TFT_WR_REG(0xC4);
TFT_WR_DATA8(0x20);
TFT_WR_REG(0xC6);
TFT_WR_DATA8(0x0F);
TFT_WR_REG(0xD0);
TFT_WR_DATA8(0xA4);
TFT_WR_DATA8(0xA1);
TFT_WR_REG(0xE0);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2B);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x54);
TFT_WR_DATA8(0x4C);
TFT_WR_DATA8(0x18);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x0B);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x23);
TFT_WR_REG(0xE1);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2C);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x44);
TFT_WR_DATA8(0x51);
TFT_WR_DATA8(0x2F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x20);
TFT_WR_DATA8(0x23);
TFT_WR_REG(0x21);
TFT_SetDisplayDir(DISP_HORIZON);
TFT_SetWindowSize(0, 0, TFTCmd.width, TFTCmd.height);
TFT_WR_REG(0x11);
delay_ms(120);
TFT_WR_REG(0x29);
TFT_WR_REG(0x2C);
TFT_ClearScreen(WHITE);
TFT_Select(0xff, 0); // UNSELECT ALL DEVICE!
TFT_BACK_LED_OPEN();
}
/**
* @brief :tft清屏
* @note :--
* @param :color,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_ClearScreen(uint16_t color)
{
TFT_FillSingleColor(0, 0, TFTCmd.width, TFTCmd.height, color);
}
/**
* @brief :
* @note :--mdk -O1时间优化时需要设置
* @param :t,
* @return :void
*
* @data :2017/03/04
* @design :
**/
//static void opt_delay(uint32_t t)
//{
// while(t--);
//}
/**
* @brief :tft读点
* @note :--
* @param :X, (0~TFTCmd.width)
Y, (0~TFTCmd.height)
* @return :uint16_t, RGB格式的颜色值
*
* @data :2017/03/04
* @design :
**/
uint16_t TFT_ReadPoint(uint16_t X, uint16_t Y)
{
return BACK_COLOR; // NO USED!
}
/**
* @brief :tft画点
* @note :--
* @param :X , (0~TFTCmd.width)
Y , (0~TFTCmd.height)
color, ()
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_DrawPoint(uint16_t X, uint16_t Y, uint16_t color)
{
if ((X >= TFTCmd.width) || (Y >= TFTCmd.height))
return;
TFT_SetCursor(X, Y, X, Y);
TFT_StartWriteRAM();
TFT_WR_DATA(color);
}
/**
* @brief :tft快速画点
* @note :--Driver_tft.c支持
* @param :X , (0~TFTCmd.width)
Y , (0~TFTCmd.height)
color,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_FastDrawPoint(uint16_t X, uint16_t Y, uint16_t color)
{
TFT_DrawPoint(X, Y, color);
}
/**
* @brief :
* @note :--:(XE-XS)*(YE-YS)
* @param :XS ,
YS ,
XE ,
YE ,
Color,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_FillSingleColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color)
{
uint16_t height, width;
width = XE - XS;
height = YE - YS;
TFT_SetCursor(XS, YS, XE-1, YE-1);
TFT_StartWriteRAM();
for (uint16_t i=0; i<width*height; i++ ) {
TFT_WR_DATA(color);
}
}
/**
* @brief :
* @note :--:(XE-XS)*(YE-YS)
* @param :XS ,
YS ,
XE ,
YE ,
*color,
* @return :void
*
* @data :2017/03/04
* @design :
**/
void TFT_FillBlockColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t *color)
{
uint16_t height, width;
width = XE - XS;
height = YE - YS;
TFT_SetCursor(XS, YS, XE-1, YE-1);
TFT_StartWriteRAM();
for (uint16_t i=0; i<width*height; i++ ) {
TFT_WR_DATA(color[i]);
}
}
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */

View File

@ -0,0 +1,149 @@
/**
******************************************************************************
*
* TFT 1.14使SPI
*
*
*
* 2022-12-07 v1.0
*
* Create 20160909
* Update 20221207
* Author dengchow
*
******************************************************************************
***/
#ifndef __TFT_SPI_H__
#define __TFT_SPI_H__
/*Needed Library Define*/
#include "__def.h"
#include "systick.h"
#include "gpio.h"
#define LCD_SPI_SOFT
#define CFG_LCD_X_SIZE LCD_X_SIZE
#define CFG_LCD_Y_SIZE LCD_Y_SIZE
/*Param Define*/
///扫描方向枚举
typedef enum
{
SCAN_L2R_U2D = (uint8_t)0, //从左到右,从上到下
SCAN_L2R_D2U = (uint8_t)1, //从左到右,从下到上
SCAN_R2L_U2D = (uint8_t)2, //从右到左,从上到下
SCAN_R2L_D2U = (uint8_t)3, //从右到左,从下到上
SCAN_U2D_L2R = (uint8_t)4, //从上到下,从左到右
SCAN_U2D_R2L = (uint8_t)5, //从上到下,从右到左
SCAN_D2U_L2R = (uint8_t)6, //从下到上,从左到右
SCAN_D2U_R2L = (uint8_t)7, //从下到上,从右到左
}_TFTScanDir;
///显示方向枚举
typedef enum
{
DISP_HORIZON = (uint8_t)0, //横向显示
DISP_PORTRAIT = (uint8_t)1, //纵向显示
}_TFTDispDir;
///tft控制参数集
typedef struct
{
uint16_t id; //ID
uint16_t width; //宽度
uint16_t height; //高度
uint16_t wramcmd; //开始写gram指令
uint16_t setxcmd; //设置x坐标指令
uint16_t setycmd; //设置y坐标指令
_TFTDispDir dir; //显示方向
}_TFTCmdTypeStruct;
extern _TFTCmdTypeStruct TFTCmd;//管理LCD重要参数
extern uint16_t POINT_COLOR;//默认黑色
extern uint16_t BACK_COLOR; //背景颜色,默认为白色
///复位控制
#define TFT_RST_PORT ;
#define TFT_RST_PIN ;
#define TFT_RST_HIGH() LCD_RST_H;
#define TFT_RST_LOW() LCD_RST_L;
///数据&命令控制
#define TFT_DC_PORT ;
#define TFT_DC_PIN ;
#define TFT_DC_DATA() LCD_DC_H;
#define TFT_DC_CMD() LCD_DC_L;
///背光灯控制
#define TFT_BACK_LED_PORT ;
#define TFT_BACK_LED_PIN ;
#define TFT_BACK_LED_OPEN() LCD_BK_ON;
#define TFT_BACK_LED_CLOSE() LCD_BK_OFF;
///扫描方向定义
#define DFT_SCAN_DIR SCAN_L2R_U2D //SCAN_D2U_L2R
///设置tft显示模式若定义则为BGR否则为RGB
#define TFT_BGR_MODE
///颜色板RGB模式下色彩值
#define WHITE 0xFFFF // 1.白色
#define BLACK 0x0000 // 2.黑色
#define RED 0x001F // 3.红色
#define BRED 0XF81F // 4.紫色(水晶葡萄色)
#define GRED 0XFFE0 // 5.青色
#define YELLOW 0X07FF // 6.黄色
#define BLUE 0xF800 // 7.蓝色
#define MAGENTA 0xF81F // 8.洋红色(偏紫偏粉色)
#define GREEN 0x07E0 // 9.绿色
#define CYAN 0x7FFF //10.淡黄色
#define BBLUE 0XBC40 //11.浅蓝色
#define GRAY 0X8430 //12.灰色
#define BROWN 0X01CF //13.棕色
#define LLGBROWN 0X7D7C //14.浅浅灰棕色(浅皮肤色)
#define LGBROWN 0X5458 //15.浅灰棕色
#define LRED 0X841F //16.浅红色(果肉色)
#define LGRAY 0XC618 //17.浅灰色
#define LGGREEN 0XA651 //18.浅灰绿色(保护眼色)
#define LBROWN 0X2B12 //19.浅棕色
#define tobgr(d) TFT_RGB2BGR(d)
#define torgb(d) TFT_BGR2RGB(d)
/*Function Define*/
///tft底层寄存器相关操作
void TFT_WR_REG(uint16_t reg);//写寄存器地址
void TFT_WR_DATA(uint16_t dat);//写数据
uint16_t TFT_RD_DATA(void);//读数据
void TFT_Select(uint8_t idx, uint8_t en);//选择lcd设备
void TFT_WriteReg(uint16_t reg, uint16_t dat);//向寄存器写数据
uint16_t TFT_ReadReg(uint16_t reg);//从寄存器读数据
void TFT_StartWriteRAM(void);//开始写GRAM
void TFT_WriteRAM(uint16_t color);//写GRAM
void TFT_DisplayOn(void);//tft开启显示
void TFT_DisplayOff(void);//tft关闭显示
void TFT_SetCursor(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2);//设置光标位置
void TFT_SetScanDir(_TFTScanDir direct);//设置tft自动扫描方向
void TFT_SetDisplayDir(_TFTDispDir direct);//设置tft显示方向
void TFT_SetWindowSize(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height);//设置tft窗口大小
///初始化相关操作
void TFT_InitConfig(void);//tft初始化设置
void TFT_ClearScreen(uint16_t color);//tft清屏
uint16_t TFT_ReadPoint(uint16_t X, uint16_t Y);//读取个某点的颜色值
void TFT_DrawPoint(uint16_t X, uint16_t Y, uint16_t color);//画点
void TFT_FastDrawPoint(uint16_t X, uint16_t Y, uint16_t color);//快速画点
void TFT_FillSingleColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//在指定区域内填充单个颜色
void TFT_FillBlockColor(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t *color);//在指定区域内填充颜色块
#endif
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */

View File

@ -0,0 +1,355 @@
/**
******************************************************************************
*
* 320*240 TFT (3.2)
*
* tft常用ASCII表(32)
* PC2LCD2002
* + + + C51格式
* 12*1216*1624*24()
* (size/8+((size%8)?1:0))*(size/2)
* size是字库生成时的点阵大小(12/16/24/...)
*
* 使()
*
* www.opencdv.com
*
*
* Create 20160909
* Update 20171015
* Author dengchow
*
******************************************************************************
***/
#ifndef __TASK_TFT_FONT_H__
#define __TASK_TFT_FONT_H__
#define _USE_FONT1608
//#define _USE_FONT2412
/*
* 12*12 -- ASCII字符集点阵
*/
const unsigned char asc_tft_1206[95][12]=
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
};
/*
* 16*16 -- ASCII字符集点阵
*/
#ifdef _USE_FONT1608
const unsigned char asc_tft_1608[95][16]=
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/
{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/
{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/
{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/
{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/
{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/
{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/
{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/
{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/
{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/
{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/
{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/
{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/
{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/
{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/
{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/
{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/
{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/
{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/
{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/
{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/
{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/
{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/
{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/
{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/
{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/
{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/
{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/
{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/
{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/
{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/
{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/
{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/
{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/
{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/
{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/
{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/
{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/
{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/
{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/
{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/
{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/
{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/
{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/
{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/
{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/
{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/
{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/
{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/
{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/
{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/
{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/
{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/
{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/
{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/
{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/
{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/
{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/
{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/
{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/
};
#endif //#ifdef _USE_FONT1608
/*
* 24*24 -- ASICII字符集点阵
*/
#ifdef _USE_FONT2412
const unsigned char asc_tft_2412[95][36]=
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0x0F,0xFE,0x38,0x0F,0x80,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x31,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x00,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x00,0x00},/*"#",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xE0,0xF0,0x06,0x30,0x08,0x04,0x18,0x08,0x1F,0xFF,0xFE,0x04,0x0E,0x08,0x07,0x87,0xF0,0x03,0x81,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"$",4*/
{0x01,0xF0,0x00,0x06,0x0C,0x00,0x04,0x04,0x08,0x06,0x0C,0x70,0x01,0xF9,0xC0,0x00,0x0E,0x00,0x00,0x3B,0xE0,0x00,0xEC,0x18,0x07,0x08,0x08,0x04,0x0C,0x18,0x00,0x03,0xE0,0x00,0x00,0x00},/*"%",5*/
{0x00,0x01,0xE0,0x00,0x07,0xF0,0x03,0xF8,0x18,0x04,0x1C,0x08,0x04,0x17,0x08,0x07,0xE1,0xD0,0x03,0xC0,0xE0,0x00,0x23,0xB0,0x00,0x3C,0x08,0x00,0x20,0x08,0x00,0x00,0x10,0x00,0x00,0x00},/*"&",6*/
{0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0xFF,0xC0,0x07,0x80,0xF0,0x0C,0x00,0x18,0x10,0x00,0x04,0x20,0x00,0x02,0x00,0x00,0x00},/*"(",8*/
{0x00,0x00,0x00,0x20,0x00,0x02,0x10,0x00,0x04,0x0C,0x00,0x18,0x07,0x80,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/
{0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x03,0xFF,0xC0,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x42,0x00},/*"*",10*/
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x01,0xFF,0xC0,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00},/*"+",11*/
{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x1C,0x00,0x00,0x70,0x00,0x01,0x80,0x00,0x0E,0x00,0x00,0x38,0x00,0x00,0xC0,0x00,0x07,0x00,0x00,0x1C,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*"/",15*/
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"0",16*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x03,0xFF,0xF8,0x07,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/
{0x00,0x00,0x00,0x01,0xC0,0x38,0x02,0xC0,0x58,0x04,0x00,0x98,0x04,0x01,0x18,0x04,0x02,0x18,0x04,0x04,0x18,0x06,0x1C,0x18,0x03,0xF8,0x18,0x01,0xE0,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/
{0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xC0,0xF0,0x04,0x00,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/
{0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x0D,0x00,0x00,0x11,0x00,0x00,0x61,0x00,0x00,0x81,0x08,0x03,0x01,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x00,0x00},/*"4",20*/
{0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xFC,0xD0,0x06,0x08,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x18,0x38,0x06,0x0F,0xF0,0x06,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x84,0x30,0x02,0x08,0x18,0x04,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x07,0x18,0x10,0x03,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"6",22*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0xF8,0x06,0x07,0xF8,0x06,0x18,0x00,0x06,0xE0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00},/*"7",23*/
{0x00,0x00,0x00,0x01,0xE1,0xE0,0x03,0xF7,0xF0,0x06,0x34,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x06,0x16,0x18,0x03,0xF3,0xF0,0x01,0xC1,0xE0,0x00,0x00,0x00},/*"8",24*/
{0x00,0x00,0x00,0x00,0xF8,0x00,0x03,0xFC,0x30,0x03,0x06,0x38,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x04,0x10,0x03,0x08,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1A,0x00,0x30,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x41,0x00,0x00,0x80,0x80,0x01,0x00,0x40,0x02,0x00,0x20,0x04,0x00,0x10,0x08,0x00,0x08,0x00,0x00,0x00},/*"<",28*/
{0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x00,0x10,0x02,0x00,0x20,0x01,0x00,0x40,0x00,0x80,0x80,0x00,0x41,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*">",30*/
{0x00,0x00,0x00,0x03,0xC0,0x00,0x04,0xC0,0x00,0x04,0x00,0x00,0x08,0x00,0x38,0x08,0x0F,0x38,0x08,0x08,0x38,0x08,0x10,0x00,0x0C,0x30,0x00,0x07,0xE0,0x00,0x03,0xC0,0x00,0x00,0x00,0x00},/*"?",31*/
{0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0xFF,0xE0,0x03,0x80,0x70,0x02,0x0F,0x10,0x06,0x70,0x88,0x04,0xC0,0x88,0x04,0x83,0x08,0x04,0x7F,0x88,0x02,0xC0,0x90,0x03,0x01,0x20,0x00,0xFE,0x40},/*"@",32*/
{0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x01,0xF8,0x00,0x3E,0x08,0x01,0xC2,0x00,0x07,0x02,0x00,0x07,0xE2,0x00,0x00,0xFE,0x00,0x00,0x1F,0xC8,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x00,0x08},/*"A",33*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00},/*"B",34*/
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x02,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x10,0x06,0x00,0x20,0x07,0x80,0xC0,0x00,0x00,0x00},/*"C",35*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x18,0x02,0x00,0x10,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"D",36*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x3E,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x01,0x00,0x60,0x00,0x00,0x00},/*"E",37*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x3E,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00},/*"F",38*/
{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x02,0x03,0xF0,0x07,0x83,0xF0,0x00,0x02,0x00,0x00,0x02,0x00},/*"G",39*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x04,0x08,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"H",40*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/
{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x03,0x07,0xFF,0xFE,0x07,0xFF,0xFC,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00},/*"J",42*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x0C,0x08,0x00,0x18,0x00,0x00,0x3E,0x00,0x04,0xC7,0x80,0x05,0x03,0xC8,0x06,0x00,0xF8,0x04,0x00,0x38,0x04,0x00,0x18,0x00,0x00,0x08},/*"K",43*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x00},/*"L",44*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x80,0x08,0x07,0xFC,0x00,0x00,0x7F,0xC0,0x00,0x03,0xF8,0x00,0x07,0xC0,0x00,0x78,0x00,0x07,0x80,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"M",45*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x00,0x08,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x38,0x00,0x00,0x1E,0x00,0x00,0x07,0x00,0x00,0x01,0xC0,0x04,0x00,0xF0,0x07,0xFF,0xF8,0x04,0x00,0x00},/*"N",46*/
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x00,0x30,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"O",47*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x04,0x08,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x06,0x0C,0x00,0x03,0xF8,0x00,0x01,0xF0,0x00,0x00,0x00,0x00},/*"P",48*/
{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x88,0x04,0x00,0x88,0x04,0x00,0xC8,0x06,0x00,0x3C,0x03,0x00,0x3E,0x01,0xFF,0xE6,0x00,0x7F,0x84,0x00,0x00,0x00},/*"Q",49*/
{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x0C,0x00,0x04,0x0F,0x00,0x04,0x0B,0xC0,0x06,0x10,0xF0,0x03,0xF0,0x38,0x01,0xE0,0x08,0x00,0x00,0x08},/*"R",50*/
{0x00,0x00,0x00,0x01,0xE0,0xF8,0x03,0xF0,0x30,0x06,0x30,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x02,0x06,0x18,0x02,0x07,0xF0,0x07,0x81,0xE0,0x00,0x00,0x00},/*"S",51*/
{0x01,0x80,0x00,0x06,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00},/*"T",52*/
{0x04,0x00,0x00,0x07,0xFF,0xE0,0x07,0xFF,0xF0,0x04,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x04,0x00,0x10,0x07,0xFF,0xE0,0x04,0x00,0x00},/*"U",53*/
{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0xE0,0x00,0x07,0xFE,0x00,0x04,0x1F,0xE0,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x01,0xE0,0x04,0x3E,0x00,0x07,0xC0,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"V",54*/
{0x04,0x00,0x00,0x07,0xE0,0x00,0x07,0xFF,0xC0,0x04,0x1F,0xF8,0x00,0x07,0xC0,0x07,0xF8,0x00,0x07,0xFF,0x80,0x04,0x3F,0xF8,0x00,0x07,0xC0,0x04,0xF8,0x00,0x07,0x00,0x00,0x04,0x00,0x00},/*"W",55*/
{0x00,0x00,0x00,0x04,0x00,0x08,0x06,0x00,0x18,0x07,0xC0,0x78,0x05,0xF1,0xC8,0x00,0x3E,0x00,0x00,0x1F,0x80,0x04,0x63,0xE8,0x07,0x80,0xF8,0x06,0x00,0x18,0x04,0x00,0x08,0x00,0x00,0x00},/*"X",56*/
{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0x80,0x00,0x07,0xE0,0x08,0x04,0x7C,0x08,0x00,0x1F,0xF8,0x00,0x07,0xF8,0x00,0x18,0x08,0x04,0xE0,0x08,0x07,0x00,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"Y",57*/
{0x00,0x00,0x00,0x01,0x00,0x08,0x06,0x00,0x38,0x04,0x00,0xF8,0x04,0x03,0xE8,0x04,0x0F,0x08,0x04,0x7C,0x08,0x05,0xF0,0x08,0x07,0xC0,0x08,0x07,0x00,0x18,0x04,0x00,0x60,0x00,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFE,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x00,0x00,0x00},/*"[",59*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x07,0x00,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0x06,0x00,0x00,0x01,0xC0,0x00,0x00,0x30,0x00,0x00,0x0E,0x00,0x00,0x01,0x00,0x00,0x00},/*"\",60*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x3F,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x10,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01},/*"_",63*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x19,0xF8,0x00,0x1B,0x18,0x00,0x22,0x08,0x00,0x26,0x08,0x00,0x24,0x08,0x00,0x24,0x10,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x18},/*"a",65*/
{0x00,0x00,0x00,0x04,0x00,0x00,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x18,0x18,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x18,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"b",66*/
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x18,0x30,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3C,0x08,0x00,0x1C,0x10,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x04,0x10,0x10,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"d",68*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x12,0x30,0x00,0x22,0x18,0x00,0x22,0x08,0x00,0x22,0x08,0x00,0x32,0x08,0x00,0x1E,0x10,0x00,0x0E,0x20,0x00,0x00,0x00},/*"e",69*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x01,0xFF,0xF8,0x03,0xFF,0xF8,0x06,0x20,0x08,0x04,0x20,0x08,0x04,0x20,0x08,0x07,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"f",70*/
{0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x6E,0x00,0x1F,0xF3,0x00,0x31,0xB1,0x00,0x20,0xB1,0x00,0x20,0xB1,0x00,0x31,0x91,0x00,0x1F,0x13,0x00,0x2E,0x1E,0x00,0x20,0x0E,0x00,0x30,0x00},/*"g",71*/
{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"h",72*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x06,0x3F,0xF8,0x06,0x3F,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x03,0x06,0x3F,0xFE,0x06,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"j",74*/
{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x88,0x00,0x03,0x00,0x00,0x2F,0xC0,0x00,0x38,0xF8,0x00,0x20,0x38,0x00,0x20,0x08,0x00,0x00,0x08,0x00,0x00,0x00},/*"k",75*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/
{0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x00,0x08},/*"m",77*/
{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"n",78*/
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x0F,0xF0,0x00,0x18,0x30,0x00,0x30,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x08,0x00,0x18,0x30,0x00,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"o",79*/
{0x00,0x00,0x00,0x00,0x20,0x01,0x00,0x3F,0xFF,0x00,0x3F,0xFF,0x00,0x10,0x11,0x00,0x20,0x09,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x38,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"p",80*/
{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x09,0x00,0x10,0x11,0x00,0x1F,0xFF,0x00,0x3F,0xFF,0x00,0x00,0x01,0x00,0x00,0x00},/*"q",81*/
{0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x08,0x08,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x78,0x00,0x1E,0x18,0x00,0x33,0x08,0x00,0x23,0x08,0x00,0x21,0x08,0x00,0x21,0x88,0x00,0x21,0x98,0x00,0x30,0xF0,0x00,0x38,0x60,0x00,0x00,0x00},/*"s",83*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0xFF,0xF0,0x03,0xFF,0xF8,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x3F,0xF0,0x00,0x7F,0xF8,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x20,0x10,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"u",85*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x3C,0x00,0x00,0x3F,0x80,0x00,0x23,0xF0,0x00,0x00,0x78,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x30,0x00,0x00,0x20,0x00},/*"v",86*/
{0x00,0x20,0x00,0x00,0x3C,0x00,0x00,0x3F,0xE0,0x00,0x23,0xF8,0x00,0x00,0xE0,0x00,0x27,0x00,0x00,0x3E,0x00,0x00,0x3F,0xE0,0x00,0x21,0xF8,0x00,0x01,0xE0,0x00,0x3E,0x00,0x00,0x20,0x00},/*"w",87*/
{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x38,0x38,0x00,0x3E,0x68,0x00,0x27,0x80,0x00,0x03,0xC8,0x00,0x2C,0xF8,0x00,0x38,0x38,0x00,0x20,0x18,0x00,0x20,0x08,0x00,0x00,0x00},/*"x",88*/
{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x03,0x00,0x3C,0x01,0x00,0x3F,0x83,0x00,0x23,0xEC,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"y",89*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x00,0x20,0x38,0x00,0x20,0xF8,0x00,0x23,0xE8,0x00,0x2F,0x88,0x00,0x3E,0x08,0x00,0x38,0x08,0x00,0x20,0x18,0x00,0x00,0x70,0x00,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x1F,0xF7,0xFC,0x30,0x00,0x06,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x30,0x00,0x06,0x1F,0xF7,0xFC,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x00,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x0C,0x00,0x00,0x10,0x00,0x00},/*"~",94*/
};
#endif //#ifdef _USE_FONT2412
#endif //#ifndef __TASK_TFT_FONT_H__
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */

1249
sim/simple/driver/Task_tft.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,167 @@
/**
******************************************************************************
*
* TFT 3.2使FSMC(stm32f407系列可用)
*
*
* 1.线
* 2.
* 3.
* 4.()
* 5.TFT的算法和OLED算法不同TFT是按点写入OLED按字节TFT不存在覆盖
* 6.
*
* 使
* 1.使emWin等成熟移植方案的测试版本
* 2.FSMC版本
* 3.GUI界面服务
*
*
*
* 2017-01-01 v1.0 oled程序
* 2017-01-02 v2.0
* 2017-01-02 v2.1
* 2017-03-05 v3.0
* 2017-03-05 v3.1
* 2018-01-023 v4.0
* 2021-03-28 v5.0 gd32f407
*
*
* Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI
* All rights reserved
*
*
* Create 20170101
* Update 20180123
* Author dengchow
*
******************************************************************************
***/
#ifndef __TASK_TFT_H__
#define __TASK_TFT_H__
/*Task_tft.h Needed Library Define*/
#include <stdint.h>
#include <stdio.h>
/*Task_tft.h Command Define*/
#define TFT_MAX_LENGTH_OF_DEC (10) //最大显示十进制位数
#define TFT_SWAP_TEMP_COLOR BLACK //颜色对调时临时替换颜色
/*Task_tft.h Param Define*/
///*移屏函数方向参数枚举*/
typedef enum
{
TFT_DIRECT_UP = (uint8_t)1,
TFT_DIRECT_DOWN = (uint8_t)2,
TFT_DIRECT_LEFT = (uint8_t)3,
TFT_DIRECT_RIGHT = (uint8_t)4,
}_TFTScrollDirect;
///*翻转函数方向参数枚举*/
typedef enum
{
TFT_TURN_L2R = (uint8_t)1,
TFT_TURN_U2D = (uint8_t)2,
}_TFTTurnDirect;
///*区域对齐函数参数枚举*/
typedef enum
{
TFT_ALIGN_H_CENTER = (uint8_t)0, //对齐方式,水平方向居中对齐(垂直水平分组按奇偶分!)
TFT_ALIGN_H_LEFT = (uint8_t)2, //对齐方式,水平方向居左对齐
TFT_ALIGN_H_RIGHT = (uint8_t)4, //对齐方式,水平方向居右对齐
TFT_ALIGN_V_CENTER = (uint8_t)1, //对齐方式,垂直方向居中对齐
TFT_ALIGN_V_TOP = (uint8_t)3, //对齐方式,垂直方向居上对齐
TFT_ALIGN_V_BOTTOM = (uint8_t)5, //对齐方式,垂直方向居下对齐
}_TFTAlignMode;
///TFT显示状态句柄
typedef struct
{
uint16_t FC; //前景板颜色(画笔)
uint16_t BC; //背景板颜色(背景)
uint16_t XS; //起始坐标
uint16_t YS; //
uint16_t XE; //终止坐标
uint16_t YE; //
uint16_t Num; //若显示字符串,这里统计字符个数!
uint8_t FontSize; //字体
}_TFTDisplayStyleStruct;
///TFT区域对齐集合
typedef struct
{
uint16_t X; //对齐后左上角横坐标
uint16_t Y; //对齐后左上角纵坐标
}_TFTAlignStruct;
extern _TFTDisplayStyleStruct DefaultStyle;//默认风格白底黑字1206字体
/*Task_tft.h Function Define*/
uint16_t TFT_BGR2RGB(uint16_t BGR);//BGR转化为RGB
uint16_t TFT_RGB2BGR(uint16_t RGB);//RGB转化为BGR
uint16_t TFT_MakeColor(uint8_t R, uint8_t G, uint8_t B);//调色函数(输入RGB三色值输出TFT的颜色值)
void TFT_GetColor(uint16_t Color, uint8_t *R, uint8_t *G, uint8_t *B);//提色函数(输入TFT的颜色值输出RGB三色值)
///图形系列函数:
void TFT_DrawBlock(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//画矩形框
void TFT_DrawRect(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height, uint16_t BlockC, uint16_t FillC);//画矩形(填充矩形)
void TFT_DrawLine(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//画实线
void TFT_DrawDottedLine(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, uint16_t color);//画虚线
void TFT_DrawCircle(uint16_t XC, uint16_t YC, uint16_t R, uint16_t color);//画圆
void TFT_DrawCircle2(uint16_t XC, uint16_t YC, uint16_t R, uint16_t color);//改进画圆
void TFT_DrawEllipse(uint16_t XC, uint16_t YC, uint16_t A, uint16_t B, uint16_t color);//画椭圆
void TFT_DrawPIC16(uint16_t XS, uint16_t YS, uint16_t width, uint16_t height, uint8_t *PIC);//画16位bmp格式图片
///Display系列函数
_TFTDisplayStyleStruct TFT_DisplayCHAR(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, char CHAR);//显示字符
_TFTDisplayStyleStruct TFT_DisplaySTR(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, char *STR);//显示字符串
_TFTDisplayStyleStruct TFT_DisplayHEX(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, uint16_t HEX);//显示转化后的16进制数字
_TFTDisplayStyleStruct TFT_DisplayINT(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, int32_t INT);//显示有符号的十进制数字
_TFTDisplayStyleStruct TFT_DisplayFLOAT(uint16_t X, uint16_t Y, _TFTDisplayStyleStruct *style, float FLOAT, uint8_t accu);//显示可变精度小数
///区域相关系列函数:
void TFT_Move(_TFTDisplayStyleStruct *area, _TFTScrollDirect direct, uint8_t loop);//移屏操作
void TFT_Turn(_TFTDisplayStyleStruct *area, _TFTTurnDirect direct);//翻转操作
uint8_t TFT_ColorChange(_TFTDisplayStyleStruct *area, uint16_t src, uint16_t tgt);//颜色替换操作
void TFT_ColorSwap(_TFTDisplayStyleStruct *area);//颜色对调操作
///显示状态设置系列函数:
void TFT_StyleStructInit(_TFTDisplayStyleStruct *style);//对创建的结构体进行初始化
void TFT_SetColorFont(uint16_t penColor, uint16_t backColor, uint8_t fontSize, _TFTDisplayStyleStruct *style);//设置前后板颜色、字体大小
void TFT_SetPosition(uint16_t XS, uint16_t YS, uint16_t XE, uint16_t YE, _TFTDisplayStyleStruct *style);//设置显示的坐标
_TFTAlignStruct TFT_Align(_TFTDisplayStyleStruct *area, _TFTAlignMode align);//区域对齐操作
#endif
/* ******************** Copyright (C), 2017-2017, TYUT TSS-plan by SERI.LJI ******************** */

26
sim/simple/init.c Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#include "__def.h"
#include "uart.h"
#include "timer.h"
#include "rtconfig.h"
extern void trap_entry();
void init(void)
{
write_csr(mtvec, &trap_entry);
write_csr(mstatus, 0x00001800);
write_csr(mtval, 0);
}

26
sim/simple/interrupt.c Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#include "__def.h"
#include "xprintf.h"
extern void timer1_handler(void);
extern void soft_handler(void);
void trap_handler(uint32_t irqno, uint32_t epc)
{
if (0x80000003 == irqno)
{
timer1_handler();
} else {
xprintf("irqno: %08x\n", irqno);
xprintf("break: %08x\n", epc);
}
}

79
sim/simple/link.lds Normal file
View File

@ -0,0 +1,79 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 28K
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 12K
}
SECTIONS
{
.init :
{
KEEP (*(SORT_NONE(.init)))
} >rom
.text :
{
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >rom
.data :
{
__data_lma = LOADADDR(.data);
__data_start = .;
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
*(.sdata .sdata.*)
*(.sdata*)
*(.gnu.linkonce.s.*)
. = ALIGN(4);
__data_end = .;
} >ram AT>rom
.bss :
{
__bss_start = .;
*(.sbss .sbss.*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
__bss_end = .;
__end = .;
} >ram
.stack ORIGIN(ram) + LENGTH(ram):
{
__stack_top = .;
} >ram
}

91
sim/simple/main.c Normal file
View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-29 Lyons first version
*/
#include "__def.h"
#include "systick.h"
#include "gpio.h"
#include "timer.h"
#include "uart.h"
#include "xprintf.h"
#include "rtthread.h"
// #define TEST_UART
// #define TEST_LCD
#ifdef TEST_LCD
#include "Driver_tftspi.h"
#include "Task_tft.h"
#endif // #ifdef TEST_LCD
int main()
{
#ifdef TEST_UART
int sum;
int mul;
int div;
sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
xprintf("add: 1+2+..+100 = %5d, expect: %5d\n", sum, 5050);
sum = 0;
for (int i = 1; i <= 100; i++) {
sum -= i;
}
xprintf("sub: -1-2-..-100 = %5d, expect: %5d\n", sum, -5050);
mul = 1;
for (int i = 1; i <= 8; i++) {
mul *= i;
}
xprintf("mul: 1*2*..*8 = %5d, expect: %5d\n", mul, 40320);
div = 19960214;
for (int i = 1; i <= 8; i++) {
div /= i;
}
xprintf("div: %d, expect: %d\n", div, 495);
#endif // #ifdef TEST_UART
#ifdef TEST_LCD
TFT_InitConfig();
TFT_Select(0xff, 1);
TFT_DisplaySTR(0, 0, &DefaultStyle, "Hello, World!");
TFT_Select(0xff, 0);
#endif // #ifdef TEST_LCD
timer_init(TIM1, CPU_FREQ_MHZ-1, (1000/RT_TICK_PER_SECOND)*1000); // tick = 1ms
timer_control(TIM1, TIM_EN);
while (1)
{
POut(0,1);
rt_thread_mdelay(500);
POut(0,0);
rt_thread_mdelay(500);
}
return 0;
}
void timer1_handler(void)
{
rt_enter_critical();
extern void rt_os_tick_callback(void);
rt_os_tick_callback();
rt_exit_critical();
}

36
sim/simple/rtthread-nano/.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
*.pyc
*.map
*.dblite
*.elf
*.bin
*.hex
*.axf
*.exe
*.pdb
*.idb
*.ilk
*.old
build
Debug
documentation/html
*~
*.o
*.obj
*.bak
*.dep
*.lib
*.a
*.i
*.d
tools/kconfig-frontends/kconfig-mconf
packages
cconfig.h
GPUCache
#cscope files
cscope.*
ncscope.*
#ctag files
tags

View File

@ -0,0 +1,45 @@
Kernel Design & Implementation
- Bernard Xiong <bernard.xiong@gmail.com>
LwIP 1.3.0/1.3.1/1.3.2/1.4.0
- Porting
Qiu Yi
Mbbill
- Testing
Bernard Xiong
Filesystem
- Porting and Add Virtual Filesystem
- Testing
Qiu Yi
prife
RTGUI
- Design and Implemenation
Bernard Xiong
Grissiom
BSP
Bernard Xiong
- ATMEL AT91SAM7S64 & AT91SAM7X256 Porting
- STM32 Porting
- S3C4510 Porting
Mbbill
- ATMEL AT91SAM7X256
Xulong Cao
- QEMU/x86
Aozima
- LPC 2148 Porting
- STM32 Porting
Jing Lee
- LPC 2478 Porting
Qiu Yi
- S3C2410 & S3C2440 Porting
- TI LM3S
others...

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-05-24 the first version
*/
#include <rthw.h>
#include <rtthread.h>
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/*
* Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
* the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
*/
#ifndef RT_HEAP_SIZE
#define RT_HEAP_SIZE (15*1024)
#endif
static rt_uint8_t rt_heap[RT_HEAP_SIZE];
RT_WEAK void *rt_heap_begin_get(void)
{
return rt_heap;
}
RT_WEAK void *rt_heap_end_get(void)
{
return rt_heap + RT_HEAP_SIZE;
}
#endif
void rt_os_tick_callback(void)
{
rt_tick_increase();
}
/**
* This function will initial your board.
*/
void rt_hw_board_init(void)
{
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
#ifdef RT_USING_CONSOLE
static int uart_init(void)
{
return 0;
}
INIT_BOARD_EXPORT(uart_init);
void rt_hw_console_output(const char *str)
{
extern void xputs(const char* str);
xputs(str);
}
#endif

View File

@ -0,0 +1,60 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
#define RT_DEBUG_INIT 0
#define RT_THREAD_PRIORITY_MAX 8
#define RT_TICK_PER_SECOND 100
#define RT_ALIGN_SIZE 4
#define RT_NAME_MAX 8
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 1024
#define IDLE_THREAD_STACK_SIZE 1024
#define RT_USING_TIMER_SOFT 0
#if RT_USING_TIMER_SOFT == 0
#undef RT_USING_TIMER_SOFT
#endif
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 1024
#define RT_USING_SEMAPHORE
// #define RT_USING_MUTEX
// #define RT_USING_EVENT
#define RT_USING_MAILBOX
// #define RT_USING_HEAP
#if defined(RT_USING_HEAP)
#define RT_HEAP_SIZE (8*1024)
#define RT_USING_SMALL_MEM
#else
#define RT_HEAP_SIZE (0)
#endif
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 256
#define RT_USING_FINSH
#if defined(RT_USING_FINSH)
#define FINSH_USING_MSH
#define FINSH_USING_MSH_ONLY
#define __FINSH_THREAD_PRIORITY 5
#define FINSH_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1)
#define FINSH_THREAD_STACK_SIZE (2*1024)
#define FINSH_HISTORY_LINES 1
#define FINSH_USING_SYMTAB
#endif
#endif

View File

@ -0,0 +1,437 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2007-01-21 Bernard the first version
* 2010-05-04 Bernard add rt_device_init implementation
* 2012-10-20 Bernard add device check in register function,
* provided by Rob <rdent@iinet.net.au>
* 2012-12-25 Bernard return RT_EOK if the device interface not exist.
* 2013-07-09 Grissiom add ref_count support
* 2016-04-02 Bernard fix the open_flag initialization issue.
*/
#include <rtthread.h>
#if defined(RT_USING_POSIX)
#include <rtdevice.h> /* for wqueue_init */
#endif
#ifdef RT_USING_DEVICE
#ifdef RT_USING_DEVICE_OPS
#define device_init (dev->ops->init)
#define device_open (dev->ops->open)
#define device_close (dev->ops->close)
#define device_read (dev->ops->read)
#define device_write (dev->ops->write)
#define device_control (dev->ops->control)
#else
#define device_init (dev->init)
#define device_open (dev->open)
#define device_close (dev->close)
#define device_read (dev->read)
#define device_write (dev->write)
#define device_control (dev->control)
#endif
/**
* This function registers a device driver with specified name.
*
* @param dev the pointer of device driver structure
* @param name the device driver's name
* @param flags the capabilities flag of device
*
* @return the error code, RT_EOK on initialization successfully.
*/
rt_err_t rt_device_register(rt_device_t dev,
const char *name,
rt_uint16_t flags)
{
if (dev == RT_NULL)
return -RT_ERROR;
if (rt_device_find(name) != RT_NULL)
return -RT_ERROR;
rt_object_init(&(dev->parent), RT_Object_Class_Device, name);
dev->flag = flags;
dev->ref_count = 0;
dev->open_flag = 0;
#if defined(RT_USING_POSIX)
dev->fops = RT_NULL;
rt_wqueue_init(&(dev->wait_queue));
#endif
return RT_EOK;
}
/**
* This function removes a previously registered device driver
*
* @param dev the pointer of device driver structure
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_device_unregister(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
RT_ASSERT(rt_object_is_systemobject(&dev->parent));
rt_object_detach(&(dev->parent));
return RT_EOK;
}
/**
* This function initializes all registered device driver
*
* @return the error code, RT_EOK on successfully.
*
* @deprecated since 1.2.x, this function is not needed because the initialization
* of a device is performed when application opens it.
*/
rt_err_t rt_device_init_all(void)
{
return RT_EOK;
}
/**
* This function finds a device driver by specified name.
*
* @param name the device driver's name
*
* @return the registered device driver on successful, or RT_NULL on failure.
*/
rt_device_t rt_device_find(const char *name)
{
return (rt_device_t)rt_object_find(name, RT_Object_Class_Device);
}
#ifdef RT_USING_HEAP
/**
* This function creates a device object with user data size.
*
* @param type, the kind type of this device object.
* @param attach_size, the size of user data.
*
* @return the allocated device object, or RT_NULL when failed.
*/
rt_device_t rt_device_create(int type, int attach_size)
{
int size;
rt_device_t device;
size = RT_ALIGN(sizeof(struct rt_device), RT_ALIGN_SIZE);
attach_size = RT_ALIGN(attach_size, RT_ALIGN_SIZE);
/* use the total size */
size += attach_size;
device = (rt_device_t)rt_malloc(size);
if (device)
{
rt_memset(device, 0x0, sizeof(struct rt_device));
device->type = (enum rt_device_class_type)type;
}
return device;
}
/**
* This function destroy the specific device object.
*
* @param dev, the specific device object.
*/
void rt_device_destroy(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
RT_ASSERT(rt_object_is_systemobject(&dev->parent) == RT_FALSE);
rt_object_detach(&(dev->parent));
/* release this device object */
rt_free(dev);
}
#endif
/**
* This function will initialize the specified device
*
* @param dev the pointer of device driver structure
*
* @return the result
*/
rt_err_t rt_device_init(rt_device_t dev)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
/* get device_init handler */
if (device_init != RT_NULL)
{
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
result = device_init(dev);
if (result != RT_EOK)
{
rt_kprintf("To initialize device:%s failed. The error code is %d\n",
dev->parent.name, result);
}
else
{
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
}
}
}
return result;
}
/**
* This function will open a device
*
* @param dev the pointer of device driver structure
* @param oflag the flags for device open
*
* @return the result
*/
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
/* if device is not initialized, initialize it. */
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
if (device_init != RT_NULL)
{
result = device_init(dev);
if (result != RT_EOK)
{
rt_kprintf("To initialize device:%s failed. The error code is %d\n",
dev->parent.name, result);
return result;
}
}
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
}
/* device is a stand alone device and opened */
if ((dev->flag & RT_DEVICE_FLAG_STANDALONE) &&
(dev->open_flag & RT_DEVICE_OFLAG_OPEN))
{
return -RT_EBUSY;
}
/* call device_open interface */
if (device_open != RT_NULL)
{
result = device_open(dev, oflag);
}
else
{
/* set open flag */
dev->open_flag = (oflag & RT_DEVICE_OFLAG_MASK);
}
/* set open flag */
if (result == RT_EOK || result == -RT_ENOSYS)
{
dev->open_flag |= RT_DEVICE_OFLAG_OPEN;
dev->ref_count++;
/* don't let bad things happen silently. If you are bitten by this assert,
* please set the ref_count to a bigger type. */
RT_ASSERT(dev->ref_count != 0);
}
return result;
}
/**
* This function will close a device
*
* @param dev the pointer of device driver structure
*
* @return the result
*/
rt_err_t rt_device_close(rt_device_t dev)
{
rt_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
if (dev->ref_count == 0)
return -RT_ERROR;
dev->ref_count--;
if (dev->ref_count != 0)
return RT_EOK;
/* call device_close interface */
if (device_close != RT_NULL)
{
result = device_close(dev);
}
/* set open flag */
if (result == RT_EOK || result == -RT_ENOSYS)
dev->open_flag = RT_DEVICE_OFLAG_CLOSE;
return result;
}
/**
* This function will read some data from a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of reading
* @param buffer the data buffer to save read data
* @param size the size of buffer
*
* @return the actually read size on successful, otherwise negative returned.
*
* @note since 0.4.0, the unit of size/pos is a block for block device.
*/
rt_size_t rt_device_read(rt_device_t dev,
rt_off_t pos,
void *buffer,
rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
if (dev->ref_count == 0)
{
rt_set_errno(-RT_ERROR);
return 0;
}
/* call device_read interface */
if (device_read != RT_NULL)
{
return device_read(dev, pos, buffer, size);
}
/* set error code */
rt_set_errno(-RT_ENOSYS);
return 0;
}
/**
* This function will write some data to a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of written
* @param buffer the data buffer to be written to device
* @param size the size of buffer
*
* @return the actually written size on successful, otherwise negative returned.
*
* @note since 0.4.0, the unit of size/pos is a block for block device.
*/
rt_size_t rt_device_write(rt_device_t dev,
rt_off_t pos,
const void *buffer,
rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
if (dev->ref_count == 0)
{
rt_set_errno(-RT_ERROR);
return 0;
}
/* call device_write interface */
if (device_write != RT_NULL)
{
return device_write(dev, pos, buffer, size);
}
/* set error code */
rt_set_errno(-RT_ENOSYS);
return 0;
}
/**
* This function will perform a variety of control functions on devices.
*
* @param dev the pointer of device driver structure
* @param cmd the command sent to device
* @param arg the argument of command
*
* @return the result
*/
rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg)
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
/* call device_write interface */
if (device_control != RT_NULL)
{
return device_control(dev, cmd, arg);
}
return -RT_ENOSYS;
}
/**
* This function will set the reception indication callback function. This callback function
* is invoked when this device receives data.
*
* @param dev the pointer of device driver structure
* @param rx_ind the indication callback function
*
* @return RT_EOK
*/
rt_err_t
rt_device_set_rx_indicate(rt_device_t dev,
rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size))
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
dev->rx_indicate = rx_ind;
return RT_EOK;
}
/**
* This function will set the indication callback function when device has
* written data to physical hardware.
*
* @param dev the pointer of device driver structure
* @param tx_done the indication callback function
*
* @return RT_EOK
*/
rt_err_t
rt_device_set_tx_complete(rt_device_t dev,
rt_err_t (*tx_done)(rt_device_t dev, void *buffer))
{
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device);
dev->tx_complete = tx_done;
return RT_EOK;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,249 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_H__
#define __FINSH_H__
#include <rtthread.h>
#include "finsh_api.h"
/* -- the beginning of option -- */
#define FINSH_NAME_MAX 16 /* max length of identifier */
#define FINSH_NODE_MAX 16 /* max number of node */
#define FINSH_HEAP_MAX 128 /* max length of heap */
#define FINSH_STRING_MAX 128 /* max length of string */
#define FINSH_VARIABLE_MAX 8 /* max number of variable */
#define FINSH_STACK_MAX 64 /* max stack size */
#define FINSH_TEXT_MAX 128 /* max text segment size */
#define HEAP_ALIGNMENT 4 /* heap alignment */
#define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
#define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
#define FINSH_SET16(x, v) \
do \
{ \
*(x) = (v) & 0x00ff; \
(*((x)+1)) = (v) >> 8; \
} while ( 0 )
#define FINSH_SET32(x, v) \
do \
{ \
*(x) = (rt_uint32_t)(v) & 0x000000ff; \
(*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
(*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
(*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
} while ( 0 )
/* -- the end of option -- */
/* std header file */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define FINSH_VERSION_MAJOR 1
#define FINSH_VERSION_MINOR 0
/**
* @addtogroup finsh
*/
/*@{*/
#define FINSH_ERROR_OK 0 /**< No error */
#define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
#define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
#define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
#define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
#define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
#define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
#define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
#define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
#define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
#define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
#define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
#define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
#define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
#define FINSH_ERROR_NULL_NODE 14 /**< Null node */
/*@}*/
/* system call item */
struct finsh_syscall_item
{
struct finsh_syscall_item* next; /* next item */
struct finsh_syscall syscall; /* syscall */
};
extern struct finsh_syscall_item *global_syscall_list;
/* system variable table */
struct finsh_sysvar
{
const char* name; /* the name of variable */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system variable */
#endif
uint8_t type; /* the type of variable */
void* var ; /* the address of variable */
};
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
#define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
#else
#define FINSH_NEXT_SYSCALL(index) index++
#define FINSH_NEXT_SYSVAR(index) index++
#endif
/* system variable item */
struct finsh_sysvar_item
{
struct finsh_sysvar_item *next; /* next item */
struct finsh_sysvar sysvar; /* system variable */
};
extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
extern struct finsh_sysvar_item* global_sysvar_list;
/* find out system variable, which should be implemented in user program */
struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
struct finsh_token
{
char eof;
char replay;
int position;
uint8_t current_token;
union {
char char_value;
int int_value;
long long_value;
} value;
uint8_t string[FINSH_STRING_MAX];
uint8_t* line;
};
#define FINSH_IDTYPE_VAR 0x01
#define FINSH_IDTYPE_SYSVAR 0x02
#define FINSH_IDTYPE_SYSCALL 0x04
#define FINSH_IDTYPE_ADDRESS 0x08
struct finsh_node
{
uint8_t node_type; /* node node_type */
uint8_t data_type; /* node data node_type */
uint8_t idtype; /* id node information */
union { /* value node */
char char_value;
short short_value;
int int_value;
long long_value;
void* ptr;
} value;
union
{
/* point to variable identifier or function identifier */
struct finsh_var *var;
struct finsh_sysvar *sysvar;
struct finsh_syscall*syscall;
}id;
/* sibling and child node */
struct finsh_node *sibling, *child;
};
struct finsh_parser
{
uint8_t* parser_string;
struct finsh_token token;
struct finsh_node* root;
};
/**
* @ingroup finsh
*
* The basic data type in finsh shell
*/
enum finsh_type {
finsh_type_unknown = 0, /**< unknown data type */
finsh_type_void, /**< void */
finsh_type_voidp, /**< void pointer */
finsh_type_char, /**< char */
finsh_type_uchar, /**< unsigned char */
finsh_type_charp, /**< char pointer */
finsh_type_short, /**< short */
finsh_type_ushort, /**< unsigned short */
finsh_type_shortp, /**< short pointer */
finsh_type_int, /**< int */
finsh_type_uint, /**< unsigned int */
finsh_type_intp, /**< int pointer */
finsh_type_long, /**< long */
finsh_type_ulong, /**< unsigned long */
finsh_type_longp /**< long pointer */
};
/* init finsh environment */
int finsh_init(struct finsh_parser* parser);
/* flush finsh node, text segment */
int finsh_flush(struct finsh_parser* parser);
/* reset all of finsh */
int finsh_reset(struct finsh_parser* parser);
#ifdef RT_USING_DEVICE
void finsh_set_device(const char* device_name);
#endif
/* run finsh parser to generate abstract synatx tree */
void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
/* run compiler to compile abstract syntax tree */
int finsh_compiler_run(struct finsh_node* node);
/* run finsh virtual machine */
void finsh_vm_run(void);
/* get variable value */
struct finsh_var* finsh_var_lookup(const char* name);
/* get bottom value of stack */
long finsh_stack_bottom(void);
/* get error number of finsh */
uint8_t finsh_errno(void);
/* get error string */
const char* finsh_error_string(uint8_t type);
#ifdef RT_USING_HEAP
/**
* @ingroup finsh
*
* This function appends a system call to finsh runtime environment
* @param name the name of system call
* @param func the function pointer of system call
*/
void finsh_syscall_append(const char* name, syscall_func func);
/**
* @ingroup finsh
*
* This function appends a system variable to finsh runtime environment
* @param name the name of system variable
* @param type the data type of system variable
* @param addr the address of system variable
*/
void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
#endif
#endif

View File

@ -0,0 +1,220 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef FINSH_API_H__
#define FINSH_API_H__
#include "finsh_config.h"
#if defined(_MSC_VER)
#pragma section("FSymTab$f",read)
#pragma section("VSymTab",read)
#endif
typedef long (*syscall_func)(void);
/* system call table */
struct finsh_syscall
{
const char* name; /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system call */
#endif
syscall_func func; /* the function address of system call */
};
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
/* find out system call, which should be implemented in user program */
struct finsh_syscall* finsh_syscall_lookup(const char* name);
#ifdef FINSH_USING_SYMTAB
#ifdef __TI_COMPILER_VERSION__
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
#define __TI_FINSH_EXPORT_VAR(v) PRAGMA(DATA_SECTION(v,"VSymTab"))
#endif
#ifdef FINSH_USING_DESCRIPTION
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
__declspec(allocate("VSymTab")) \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#endif
#else
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
__declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
RT_USED const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
RT_USED const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#endif
#endif /* end of FINSH_USING_DESCRIPTION */
#endif /* end of FINSH_USING_SYMTAB */
/**
* @ingroup finsh
*
* This macro exports a system function to finsh shell.
*
* @param name the name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT(name, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
/**
* @ingroup finsh
*
* This macro exports a system function with an alias name to finsh shell.
*
* @param name the name of function.
* @param alias the alias name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
/**
* @ingroup finsh
*
* This macro exports a command to module shell.
*
* @param command the name of command.
* @param desc the description of command, which will show in help.
*/
#ifdef FINSH_USING_MSH
#define MSH_CMD_EXPORT(command, desc) \
FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
#else
#define MSH_CMD_EXPORT(command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
#endif
#endif

View File

@ -0,0 +1,7 @@
/* FinSH config file */
#ifndef __MSH_CFG_H__
#define __MSH_CFG_H__
#endif

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtconfig.h>
#ifndef RT_USING_FINSH
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
#endif
#ifdef RT_USING_FINSH
#include "uart.h"
RT_WEAK char rt_hw_console_getchar(void)
{
rt_uint8_t ch;
extern uint8_t uart_read_wait(UART_Type *uart);
ch = uart_read_wait(UART1);
return ch;
}
#endif /* RT_USING_FINSH */

View File

@ -0,0 +1,648 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion for finsh
* 2014-01-03 Bernard msh can execute module.
* 2017-07-19 Aubr.Cool limit argc to RT_FINSH_ARG_MAX
*/
#include <rtthread.h>
#include <finsh_config.h>
#ifdef FINSH_USING_MSH
#include "msh.h"
#include <finsh.h>
#include <shell.h>
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#endif
#ifdef RT_USING_MODULE
#include <dlmodule.h>
#endif
#ifndef FINSH_ARG_MAX
#define FINSH_ARG_MAX 8
#endif
typedef int (*cmd_function_t)(int argc, char **argv);
#ifdef FINSH_USING_MSH
#ifdef FINSH_USING_MSH_ONLY
rt_bool_t msh_is_used(void)
{
return RT_TRUE;
}
#else
#ifdef FINSH_USING_MSH_DEFAULT
static rt_bool_t __msh_state = RT_TRUE;
#else
static rt_bool_t __msh_state = RT_FALSE;
#endif
rt_bool_t msh_is_used(void)
{
return __msh_state;
}
static int msh_exit(int argc, char **argv)
{
/* return to finsh shell mode */
__msh_state = RT_FALSE;
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_exit, __cmd_exit, return to RT-Thread shell mode.);
static int msh_enter(void)
{
/* enter module shell mode */
__msh_state = RT_TRUE;
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_enter, msh, use module shell);
#endif
int msh_help(int argc, char **argv)
{
rt_kprintf("RT-Thread shell commands:\n");
{
struct finsh_syscall *index;
for (index = _syscall_table_begin;
index < _syscall_table_end;
FINSH_NEXT_SYSCALL(index))
{
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
rt_kprintf("%-16s - %s\n", &index->name[6], index->desc);
#else
rt_kprintf("%s ", &index->name[6]);
#endif
}
}
rt_kprintf("\n");
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_help, __cmd_help, RT-Thread shell help.);
int cmd_ps(int argc, char **argv)
{
extern long list_thread(void);
extern int list_module(void);
#ifdef RT_USING_MODULE
if ((argc == 2) && (strcmp(argv[1], "-m") == 0))
list_module();
else
#endif
list_thread();
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.);
#ifdef RT_USING_HEAP
int cmd_free(int argc, char **argv)
{
extern void list_mem(void);
extern void list_memheap(void);
#ifdef RT_USING_MEMHEAP_AS_HEAP
list_memheap();
#else
list_mem();
#endif
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.);
#endif
static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
{
char *ptr;
rt_size_t position;
rt_size_t argc;
rt_size_t i;
ptr = cmd;
position = 0; argc = 0;
while (position < length)
{
/* strip bank and tab */
while ((*ptr == ' ' || *ptr == '\t') && position < length)
{
*ptr = '\0';
ptr ++; position ++;
}
if(argc >= FINSH_ARG_MAX)
{
rt_kprintf("Too many args ! We only Use:\n");
for(i = 0; i < argc; i++)
{
rt_kprintf("%s ", argv[i]);
}
rt_kprintf("\n");
break;
}
if (position >= length) break;
/* handle string */
if (*ptr == '"')
{
ptr ++; position ++;
argv[argc] = ptr; argc ++;
/* skip this string */
while (*ptr != '"' && position < length)
{
if (*ptr == '\\')
{
if (*(ptr + 1) == '"')
{
ptr ++; position ++;
}
}
ptr ++; position ++;
}
if (position >= length) break;
/* skip '"' */
*ptr = '\0'; ptr ++; position ++;
}
else
{
argv[argc] = ptr;
argc ++;
while ((*ptr != ' ' && *ptr != '\t') && position < length)
{
ptr ++; position ++;
}
if (position >= length) break;
}
}
return argc;
}
static cmd_function_t msh_get_cmd(char *cmd, int size)
{
struct finsh_syscall *index;
cmd_function_t cmd_func = RT_NULL;
for (index = _syscall_table_begin;
index < _syscall_table_end;
FINSH_NEXT_SYSCALL(index))
{
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
if (strncmp(&index->name[6], cmd, size) == 0 &&
index->name[6 + size] == '\0')
{
cmd_func = (cmd_function_t)index->func;
break;
}
}
return cmd_func;
}
#if defined(RT_USING_MODULE) && defined(RT_USING_DFS)
/* Return 0 on module executed. Other value indicate error.
*/
int msh_exec_module(const char *cmd_line, int size)
{
int ret;
int fd = -1;
char *pg_name;
int length, cmd_length = 0;
if (size == 0)
return -RT_ERROR;
/* get the length of command0 */
while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size)
cmd_length ++;
/* get name length */
length = cmd_length + 32;
/* allocate program name memory */
pg_name = (char *) rt_malloc(length);
if (pg_name == RT_NULL)
return -RT_ENOMEM;
/* copy command0 */
memcpy(pg_name, cmd_line, cmd_length);
pg_name[cmd_length] = '\0';
if (strstr(pg_name, ".mo") != RT_NULL || strstr(pg_name, ".MO") != RT_NULL)
{
/* try to open program */
fd = open(pg_name, O_RDONLY, 0);
/* search in /bin path */
if (fd < 0)
{
rt_snprintf(pg_name, length - 1, "/bin/%.*s", cmd_length, cmd_line);
fd = open(pg_name, O_RDONLY, 0);
}
}
else
{
/* add .mo and open program */
/* try to open program */
strcat(pg_name, ".mo");
fd = open(pg_name, O_RDONLY, 0);
/* search in /bin path */
if (fd < 0)
{
rt_snprintf(pg_name, length - 1, "/bin/%.*s.mo", cmd_length, cmd_line);
fd = open(pg_name, O_RDONLY, 0);
}
}
if (fd >= 0)
{
/* found program */
close(fd);
dlmodule_exec(pg_name, cmd_line, size);
ret = 0;
}
else
{
ret = -1;
}
rt_free(pg_name);
return ret;
}
int system(const char *command)
{
int ret = -RT_ENOMEM;
char *cmd = rt_strdup(command);
if (cmd)
{
ret = msh_exec(cmd, rt_strlen(cmd));
rt_free(cmd);
}
return ret;
}
#endif
static int _msh_exec_cmd(char *cmd, rt_size_t length, int *retp)
{
int argc;
rt_size_t cmd0_size = 0;
cmd_function_t cmd_func;
char *argv[FINSH_ARG_MAX];
RT_ASSERT(cmd);
RT_ASSERT(retp);
/* find the size of first command */
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
cmd0_size ++;
if (cmd0_size == 0)
return -RT_ERROR;
cmd_func = msh_get_cmd(cmd, cmd0_size);
if (cmd_func == RT_NULL)
return -RT_ERROR;
/* split arguments */
memset(argv, 0x00, sizeof(argv));
argc = msh_split(cmd, length, argv);
if (argc == 0)
return -RT_ERROR;
/* exec this command */
*retp = cmd_func(argc, argv);
return 0;
}
#if defined(RT_USING_LWP) && defined(RT_USING_DFS)
static int _msh_exec_lwp(char *cmd, rt_size_t length)
{
int argc;
int cmd0_size = 0;
char *argv[FINSH_ARG_MAX];
int fd = -1;
char *pg_name;
extern int exec(char*, int, char**);
/* find the size of first command */
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
cmd0_size ++;
if (cmd0_size == 0)
return -1;
/* split arguments */
rt_memset(argv, 0x00, sizeof(argv));
argc = msh_split(cmd, length, argv);
if (argc == 0)
return -1;
pg_name = argv[0];
/* try to open program */
fd = open(pg_name, O_RDONLY, 0);
if (fd < 0)
return -1;
/* found program */
close(fd);
exec(pg_name, argc, argv);
return 0;
}
#endif
int msh_exec(char *cmd, rt_size_t length)
{
int cmd_ret;
/* strim the beginning of command */
while ((length > 0) && (*cmd == ' ' || *cmd == '\t'))
{
cmd++;
length--;
}
if (length == 0)
return 0;
/* Exec sequence:
* 1. built-in command
* 2. module(if enabled)
*/
if (_msh_exec_cmd(cmd, length, &cmd_ret) == 0)
{
return cmd_ret;
}
#ifdef RT_USING_DFS
#ifdef DFS_USING_WORKDIR
if (msh_exec_script(cmd, length) == 0)
{
return 0;
}
#endif
#ifdef RT_USING_MODULE
if (msh_exec_module(cmd, length) == 0)
{
return 0;
}
#endif
#ifdef RT_USING_LWP
if (_msh_exec_lwp(cmd, length) == 0)
{
return 0;
}
#endif
#endif
/* truncate the cmd at the first space. */
{
char *tcmd;
tcmd = cmd;
while (*tcmd != ' ' && *tcmd != '\0')
{
tcmd++;
}
*tcmd = '\0';
}
rt_kprintf("%s: command not found.\n", cmd);
return -1;
}
static int str_common(const char *str1, const char *str2)
{
const char *str = str1;
while ((*str != 0) && (*str2 != 0) && (*str == *str2))
{
str ++;
str2 ++;
}
return (str - str1);
}
#ifdef RT_USING_DFS
void msh_auto_complete_path(char *path)
{
DIR *dir = RT_NULL;
struct dirent *dirent = RT_NULL;
char *full_path, *ptr, *index;
if (!path)
return;
full_path = (char *)rt_malloc(256);
if (full_path == RT_NULL) return; /* out of memory */
if (*path != '/')
{
getcwd(full_path, 256);
if (full_path[rt_strlen(full_path) - 1] != '/')
strcat(full_path, "/");
}
else *full_path = '\0';
index = RT_NULL;
ptr = path;
for (;;)
{
if (*ptr == '/') index = ptr + 1;
if (!*ptr) break;
ptr ++;
}
if (index == RT_NULL) index = path;
if (index != RT_NULL)
{
char *dest = index;
/* fill the parent path */
ptr = full_path;
while (*ptr) ptr ++;
for (index = path; index != dest;)
*ptr++ = *index++;
*ptr = '\0';
dir = opendir(full_path);
if (dir == RT_NULL) /* open directory failed! */
{
rt_free(full_path);
return;
}
/* restore the index position */
index = dest;
}
/* auto complete the file or directory name */
if (*index == '\0') /* display all of files and directories */
{
for (;;)
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
rt_kprintf("%s\n", dirent->d_name);
}
}
else
{
rt_size_t length, min_length;
min_length = 0;
for (;;)
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
/* matched the prefix string */
if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
{
if (min_length == 0)
{
min_length = rt_strlen(dirent->d_name);
/* save dirent name */
strcpy(full_path, dirent->d_name);
}
length = str_common(dirent->d_name, full_path);
if (length < min_length)
{
min_length = length;
}
}
}
if (min_length)
{
if (min_length < rt_strlen(full_path))
{
/* list the candidate */
rewinddir(dir);
for (;;)
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
if (strncmp(index, dirent->d_name, rt_strlen(index)) == 0)
rt_kprintf("%s\n", dirent->d_name);
}
}
length = index - path;
memcpy(index, full_path, min_length);
path[length + min_length] = '\0';
}
}
closedir(dir);
rt_free(full_path);
}
#endif
void msh_auto_complete(char *prefix)
{
int length, min_length;
const char *name_ptr, *cmd_name;
struct finsh_syscall *index;
min_length = 0;
name_ptr = RT_NULL;
if (*prefix == '\0')
{
msh_help(0, RT_NULL);
return;
}
#ifdef RT_USING_DFS
/* check whether a spare in the command */
{
char *ptr;
ptr = prefix + rt_strlen(prefix);
while (ptr != prefix)
{
if (*ptr == ' ')
{
msh_auto_complete_path(ptr + 1);
break;
}
ptr --;
}
#ifdef RT_USING_MODULE
/* There is a chance that the user want to run the module directly. So
* try to complete the file names. If the completed path is not a
* module, the system won't crash anyway. */
if (ptr == prefix)
{
msh_auto_complete_path(ptr);
}
#endif
}
#endif
/* checks in internal command */
{
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
/* skip finsh shell function */
if (strncmp(index->name, "__cmd_", 6) != 0) continue;
cmd_name = (const char *) &index->name[6];
if (strncmp(prefix, cmd_name, strlen(prefix)) == 0)
{
if (min_length == 0)
{
/* set name_ptr */
name_ptr = cmd_name;
/* set initial length */
min_length = strlen(name_ptr);
}
length = str_common(name_ptr, cmd_name);
if (length < min_length)
min_length = length;
rt_kprintf("%s\n", cmd_name);
}
}
}
/* auto complete string */
if (name_ptr != NULL)
{
rt_strncpy(prefix, name_ptr, min_length);
}
return ;
}
#endif
#endif /* FINSH_USING_MSH */

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion for FinSH
*/
#ifndef __M_SHELL__
#define __M_SHELL__
#include <rtthread.h>
rt_bool_t msh_is_used(void);
int msh_exec(char *cmd, rt_size_t length);
void msh_auto_complete(char *prefix);
int msh_exec_module(const char *cmd_line, int size);
int msh_exec_script(const char *cmd_line, int size);
#endif

View File

@ -0,0 +1,904 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-04-30 Bernard the first version for FinSH
* 2006-05-08 Bernard change finsh thread stack to 2048
* 2006-06-03 Bernard add support for skyeye
* 2006-09-24 Bernard remove the code related with hardware
* 2010-01-18 Bernard fix down then up key bug.
* 2010-03-19 Bernard fix backspace issue and fix device read in shell.
* 2010-04-01 Bernard add prompt output when start and remove the empty history
* 2011-02-23 Bernard fix variable section end issue of finsh shell
* initialization when use GNU GCC compiler.
* 2016-11-26 armink add password authentication
* 2018-07-02 aozima add custome prompt support.
*/
#include <rthw.h>
#include <finsh_config.h>
#ifdef RT_USING_FINSH
#include "finsh.h"
#include "shell.h"
#ifdef FINSH_USING_MSH
#include "msh.h"
#endif
#ifdef _WIN32
#include <stdio.h> /* for putchar */
#endif
/* finsh thread */
#ifndef RT_USING_HEAP
static struct rt_thread finsh_thread;
ALIGN(RT_ALIGN_SIZE)
static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
struct finsh_shell _shell;
#endif
/* finsh symtab */
#ifdef FINSH_USING_SYMTAB
struct finsh_syscall *_syscall_table_begin = NULL;
struct finsh_syscall *_syscall_table_end = NULL;
struct finsh_sysvar *_sysvar_table_begin = NULL;
struct finsh_sysvar *_sysvar_table_end = NULL;
#endif
struct finsh_shell *shell;
static char *finsh_prompt_custom = RT_NULL;
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
{
unsigned int *ptr;
ptr = (unsigned int*) (call + 1);
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
ptr ++;
return (struct finsh_syscall*)ptr;
}
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
{
unsigned int *ptr;
ptr = (unsigned int*) (call + 1);
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
ptr ++;
return (struct finsh_sysvar*)ptr;
}
#endif /* defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) */
#ifdef RT_USING_HEAP
int finsh_set_prompt(const char * prompt)
{
if(finsh_prompt_custom)
{
rt_free(finsh_prompt_custom);
finsh_prompt_custom = RT_NULL;
}
/* strdup */
if(prompt)
{
finsh_prompt_custom = (char *)rt_malloc(strlen(prompt)+1);
if(finsh_prompt_custom)
{
strcpy(finsh_prompt_custom, prompt);
}
}
return 0;
}
#endif /* RT_USING_HEAP */
#if defined(RT_USING_DFS)
#include <dfs_posix.h>
#endif /* RT_USING_DFS */
const char *finsh_get_prompt()
{
#define _MSH_PROMPT "msh "
#define _PROMPT "finsh "
static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};
/* check prompt mode */
if (!shell->prompt_mode)
{
finsh_prompt[0] = '\0';
return finsh_prompt;
}
if(finsh_prompt_custom)
{
strncpy(finsh_prompt, finsh_prompt_custom, sizeof(finsh_prompt)-1);
return finsh_prompt;
}
#ifdef FINSH_USING_MSH
if (msh_is_used()) strcpy(finsh_prompt, _MSH_PROMPT);
else
#endif
strcpy(finsh_prompt, _PROMPT);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
/* get current working directory */
getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt));
#endif
strcat(finsh_prompt, ">");
return finsh_prompt;
}
/**
* @ingroup finsh
*
* This function get the prompt mode of finsh shell.
*
* @return prompt the prompt mode, 0 disable prompt mode, other values enable prompt mode.
*/
rt_uint32_t finsh_get_prompt_mode(void)
{
RT_ASSERT(shell != RT_NULL);
return shell->prompt_mode;
}
/**
* @ingroup finsh
*
* This function set the prompt mode of finsh shell.
*
* The parameter 0 disable prompt mode, other values enable prompt mode.
*
* @param prompt the prompt mode
*/
void finsh_set_prompt_mode(rt_uint32_t prompt_mode)
{
RT_ASSERT(shell != RT_NULL);
shell->prompt_mode = prompt_mode;
}
static int finsh_getchar(void)
{
#ifdef RT_USING_DEVICE
#ifdef RT_USING_POSIX
return getchar();
#else
char ch = 0;
RT_ASSERT(shell != RT_NULL);
if(shell->device)
{
while (rt_device_read(shell->device, -1, &ch, 1) != 1)
rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER);
return (int)ch;
}
else
#endif
#endif
{
extern char rt_hw_console_getchar(void);
return rt_hw_console_getchar();
}
}
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size)
{
RT_ASSERT(shell != RT_NULL);
/* release semaphore to let finsh thread rx data */
rt_sem_release(&shell->rx_sem);
return RT_EOK;
}
/**
* @ingroup finsh
*
* This function sets the input device of finsh shell.
*
* @param device_name the name of new input device.
*/
void finsh_set_device(const char *device_name)
{
rt_device_t dev = RT_NULL;
RT_ASSERT(shell != RT_NULL);
dev = rt_device_find(device_name);
if (dev == RT_NULL)
{
rt_kprintf("finsh: can not find device: %s\n", device_name);
return;
}
/* check whether it's a same device */
if (dev == shell->device) return;
/* open this device and set the new device in finsh shell */
if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | \
RT_DEVICE_FLAG_STREAM) == RT_EOK)
{
if (shell->device != RT_NULL)
{
/* close old finsh device */
rt_device_close(shell->device);
rt_device_set_rx_indicate(shell->device, RT_NULL);
}
/* clear line buffer before switch to new device */
memset(shell->line, 0, sizeof(shell->line));
shell->line_curpos = shell->line_position = 0;
shell->device = dev;
rt_device_set_rx_indicate(dev, finsh_rx_ind);
}
}
/**
* @ingroup finsh
*
* This function returns current finsh shell input device.
*
* @return the finsh shell input device name is returned.
*/
const char *finsh_get_device()
{
RT_ASSERT(shell != RT_NULL);
return shell->device->parent.name;
}
#endif
/**
* @ingroup finsh
*
* This function set the echo mode of finsh shell.
*
* FINSH_OPTION_ECHO=0x01 is echo mode, other values are none-echo mode.
*
* @param echo the echo mode
*/
void finsh_set_echo(rt_uint32_t echo)
{
RT_ASSERT(shell != RT_NULL);
shell->echo_mode = (rt_uint8_t)echo;
}
/**
* @ingroup finsh
*
* This function gets the echo mode of finsh shell.
*
* @return the echo mode
*/
rt_uint32_t finsh_get_echo()
{
RT_ASSERT(shell != RT_NULL);
return shell->echo_mode;
}
#ifdef FINSH_USING_AUTH
/**
* set a new password for finsh
*
* @param password new password
*
* @return result, RT_EOK on OK, -RT_ERROR on the new password length is less than
* FINSH_PASSWORD_MIN or greater than FINSH_PASSWORD_MAX
*/
rt_err_t finsh_set_password(const char *password) {
rt_ubase_t level;
rt_size_t pw_len = rt_strlen(password);
if (pw_len < FINSH_PASSWORD_MIN || pw_len > FINSH_PASSWORD_MAX)
return -RT_ERROR;
level = rt_hw_interrupt_disable();
rt_strncpy(shell->password, password, FINSH_PASSWORD_MAX);
rt_hw_interrupt_enable(level);
return RT_EOK;
}
/**
* get the finsh password
*
* @return password
*/
const char *finsh_get_password(void)
{
return shell->password;
}
static void finsh_wait_auth(void)
{
int ch;
rt_bool_t input_finish = RT_FALSE;
char password[FINSH_PASSWORD_MAX] = { 0 };
rt_size_t cur_pos = 0;
/* password not set */
if (rt_strlen(finsh_get_password()) == 0) return;
while (1)
{
rt_kprintf("Password for login: ");
while (!input_finish)
{
while (1)
{
/* read one character from device */
ch = finsh_getchar();
if (ch < 0)
{
continue;
}
if (ch >= ' ' && ch <= '~' && cur_pos < FINSH_PASSWORD_MAX)
{
/* change the printable characters to '*' */
rt_kprintf("*");
password[cur_pos++] = ch;
}
else if (ch == '\b' && cur_pos > 0)
{
/* backspace */
cur_pos--;
password[cur_pos] = '\0';
rt_kprintf("\b \b");
}
else if (ch == '\r' || ch == '\n')
{
rt_kprintf("\n");
input_finish = RT_TRUE;
break;
}
}
}
if (!rt_strncmp(shell->password, password, FINSH_PASSWORD_MAX)) return;
else
{
/* authentication failed, delay 2S for retry */
rt_thread_delay(2 * RT_TICK_PER_SECOND);
rt_kprintf("Sorry, try again.\n");
cur_pos = 0;
input_finish = RT_FALSE;
rt_memset(password, '\0', FINSH_PASSWORD_MAX);
}
}
}
#endif /* FINSH_USING_AUTH */
static void shell_auto_complete(char *prefix)
{
rt_kprintf("\n");
#ifdef FINSH_USING_MSH
if (msh_is_used() == RT_TRUE)
{
msh_auto_complete(prefix);
}
else
#endif
{
#ifndef FINSH_USING_MSH_ONLY
extern void list_prefix(char * prefix);
list_prefix(prefix);
#endif
}
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
}
#ifndef FINSH_USING_MSH_ONLY
void finsh_run_line(struct finsh_parser *parser, const char *line)
{
const char *err_str;
if(shell->echo_mode)
rt_kprintf("\n");
finsh_parser_run(parser, (unsigned char *)line);
/* compile node root */
if (finsh_errno() == 0)
{
finsh_compiler_run(parser->root);
}
else
{
err_str = finsh_error_string(finsh_errno());
rt_kprintf("%s\n", err_str);
}
/* run virtual machine */
if (finsh_errno() == 0)
{
char ch;
finsh_vm_run();
ch = (unsigned char)finsh_stack_bottom();
if (ch > 0x20 && ch < 0x7e)
{
rt_kprintf("\t'%c', %d, 0x%08x\n",
(unsigned char)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom());
}
else
{
rt_kprintf("\t%d, 0x%08x\n",
(unsigned int)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom());
}
}
finsh_flush(parser);
}
#endif
#ifdef FINSH_USING_HISTORY
static rt_bool_t shell_handle_history(struct finsh_shell *shell)
{
#if defined(_WIN32)
int i;
rt_kprintf("\r");
for (i = 0; i <= 60; i++)
putchar(' ');
rt_kprintf("\r");
#else
rt_kprintf("\033[2K\r");
#endif
rt_kprintf("%s%s", FINSH_PROMPT, shell->line);
return RT_FALSE;
}
static void shell_push_history(struct finsh_shell *shell)
{
if (shell->line_position != 0)
{
/* push history */
if (shell->history_count >= FINSH_HISTORY_LINES)
{
/* if current cmd is same as last cmd, don't push */
if (memcmp(&shell->cmd_history[FINSH_HISTORY_LINES - 1], shell->line, FINSH_CMD_SIZE))
{
/* move history */
int index;
for (index = 0; index < FINSH_HISTORY_LINES - 1; index ++)
{
memcpy(&shell->cmd_history[index][0],
&shell->cmd_history[index + 1][0], FINSH_CMD_SIZE);
}
memset(&shell->cmd_history[index][0], 0, FINSH_CMD_SIZE);
memcpy(&shell->cmd_history[index][0], shell->line, shell->line_position);
/* it's the maximum history */
shell->history_count = FINSH_HISTORY_LINES;
}
}
else
{
/* if current cmd is same as last cmd, don't push */
if (shell->history_count == 0 || memcmp(&shell->cmd_history[shell->history_count - 1], shell->line, FINSH_CMD_SIZE))
{
shell->current_history = shell->history_count;
memset(&shell->cmd_history[shell->history_count][0], 0, FINSH_CMD_SIZE);
memcpy(&shell->cmd_history[shell->history_count][0], shell->line, shell->line_position);
/* increase count and set current history position */
shell->history_count ++;
}
}
}
shell->current_history = shell->history_count;
}
#endif
void finsh_thread_entry(void *parameter)
{
int ch;
/* normal is echo mode */
#ifndef FINSH_ECHO_DISABLE_DEFAULT
shell->echo_mode = 1;
#else
shell->echo_mode = 0;
#endif
#ifndef FINSH_USING_MSH_ONLY
finsh_init(&shell->parser);
#endif
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
/* set console device as shell device */
if (shell->device == RT_NULL)
{
rt_device_t console = rt_console_get_device();
if (console)
{
finsh_set_device(console->parent.name);
}
}
#endif
#ifdef FINSH_USING_AUTH
/* set the default password when the password isn't setting */
if (rt_strlen(finsh_get_password()) == 0)
{
if (finsh_set_password(FINSH_DEFAULT_PASSWORD) != RT_EOK)
{
rt_kprintf("Finsh password set failed.\n");
}
}
/* waiting authenticate success */
finsh_wait_auth();
#endif
rt_kprintf(FINSH_PROMPT);
while (1)
{
ch = finsh_getchar();
if (ch < 0)
{
continue;
}
/*
* handle control key
* up key : 0x1b 0x5b 0x41
* down key: 0x1b 0x5b 0x42
* right key:0x1b 0x5b 0x43
* left key: 0x1b 0x5b 0x44
*/
if (ch == 0x1b)
{
shell->stat = WAIT_SPEC_KEY;
continue;
}
else if (shell->stat == WAIT_SPEC_KEY)
{
if (ch == 0x5b)
{
shell->stat = WAIT_FUNC_KEY;
continue;
}
shell->stat = WAIT_NORMAL;
}
else if (shell->stat == WAIT_FUNC_KEY)
{
shell->stat = WAIT_NORMAL;
if (ch == 0x41) /* up key */
{
#ifdef FINSH_USING_HISTORY
/* prev history */
if (shell->current_history > 0)
shell->current_history --;
else
{
shell->current_history = 0;
continue;
}
/* copy the history command */
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
FINSH_CMD_SIZE);
shell->line_curpos = shell->line_position = strlen(shell->line);
shell_handle_history(shell);
#endif
continue;
}
else if (ch == 0x42) /* down key */
{
#ifdef FINSH_USING_HISTORY
/* next history */
if (shell->current_history < shell->history_count - 1)
shell->current_history ++;
else
{
/* set to the end of history */
if (shell->history_count != 0)
shell->current_history = shell->history_count - 1;
else
continue;
}
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
FINSH_CMD_SIZE);
shell->line_curpos = shell->line_position = strlen(shell->line);
shell_handle_history(shell);
#endif
continue;
}
else if (ch == 0x44) /* left key */
{
if (shell->line_curpos)
{
rt_kprintf("\b");
shell->line_curpos --;
}
continue;
}
else if (ch == 0x43) /* right key */
{
if (shell->line_curpos < shell->line_position)
{
rt_kprintf("%c", shell->line[shell->line_curpos]);
shell->line_curpos ++;
}
continue;
}
}
/* received null or error */
if (ch == '\0' || ch == 0xFF) continue;
/* handle tab key */
else if (ch == '\t')
{
int i;
/* move the cursor to the beginning of line */
for (i = 0; i < shell->line_curpos; i++)
rt_kprintf("\b");
/* auto complete */
shell_auto_complete(&shell->line[0]);
/* re-calculate position */
shell->line_curpos = shell->line_position = strlen(shell->line);
continue;
}
/* handle backspace key */
else if (ch == 0x7f || ch == 0x08)
{
/* note that shell->line_curpos >= 0 */
if (shell->line_curpos == 0)
continue;
shell->line_position--;
shell->line_curpos--;
if (shell->line_position > shell->line_curpos)
{
int i;
rt_memmove(&shell->line[shell->line_curpos],
&shell->line[shell->line_curpos + 1],
shell->line_position - shell->line_curpos);
shell->line[shell->line_position] = 0;
rt_kprintf("\b%s \b", &shell->line[shell->line_curpos]);
/* move the cursor to the origin position */
for (i = shell->line_curpos; i <= shell->line_position; i++)
rt_kprintf("\b");
}
else
{
rt_kprintf("\b \b");
shell->line[shell->line_position] = 0;
}
continue;
}
/* handle end of line, break */
if (ch == '\r' || ch == '\n')
{
#ifdef FINSH_USING_HISTORY
shell_push_history(shell);
#endif
#ifdef FINSH_USING_MSH
if (msh_is_used() == RT_TRUE)
{
if (shell->echo_mode)
rt_kprintf("\n");
msh_exec(shell->line, shell->line_position);
}
else
#endif
{
#ifndef FINSH_USING_MSH_ONLY
/* add ';' and run the command line */
shell->line[shell->line_position] = ';';
if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
else
if (shell->echo_mode) rt_kprintf("\n");
#endif
}
rt_kprintf(FINSH_PROMPT);
memset(shell->line, 0, sizeof(shell->line));
shell->line_curpos = shell->line_position = 0;
continue;
}
/* it's a large line, discard it */
if (shell->line_position >= FINSH_CMD_SIZE)
shell->line_position = 0;
/* normal character */
if (shell->line_curpos < shell->line_position)
{
int i;
rt_memmove(&shell->line[shell->line_curpos + 1],
&shell->line[shell->line_curpos],
shell->line_position - shell->line_curpos);
shell->line[shell->line_curpos] = ch;
if (shell->echo_mode)
rt_kprintf("%s", &shell->line[shell->line_curpos]);
/* move the cursor to new position */
for (i = shell->line_curpos; i < shell->line_position; i++)
rt_kprintf("\b");
}
else
{
shell->line[shell->line_position] = ch;
if (shell->echo_mode)
rt_kprintf("%c", ch);
}
ch = 0;
shell->line_position ++;
shell->line_curpos++;
if (shell->line_position >= FINSH_CMD_SIZE)
{
/* clear command line */
shell->line_position = 0;
shell->line_curpos = 0;
}
} /* end of device read */
}
void finsh_system_function_init(const void *begin, const void *end)
{
_syscall_table_begin = (struct finsh_syscall *) begin;
_syscall_table_end = (struct finsh_syscall *) end;
}
void finsh_system_var_init(const void *begin, const void *end)
{
_sysvar_table_begin = (struct finsh_sysvar *) begin;
_sysvar_table_end = (struct finsh_sysvar *) end;
}
#if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */
#ifdef FINSH_USING_SYMTAB
#pragma section="FSymTab"
#pragma section="VSymTab"
#endif
#elif defined(__ADSPBLACKFIN__) /* for VisaulDSP++ Compiler*/
#ifdef FINSH_USING_SYMTAB
extern "asm" int __fsymtab_start;
extern "asm" int __fsymtab_end;
extern "asm" int __vsymtab_start;
extern "asm" int __vsymtab_end;
#endif
#elif defined(_MSC_VER)
#pragma section("FSymTab$a", read)
const char __fsym_begin_name[] = "__start";
const char __fsym_begin_desc[] = "begin of finsh";
__declspec(allocate("FSymTab$a")) const struct finsh_syscall __fsym_begin =
{
__fsym_begin_name,
__fsym_begin_desc,
NULL
};
#pragma section("FSymTab$z", read)
const char __fsym_end_name[] = "__end";
const char __fsym_end_desc[] = "end of finsh";
__declspec(allocate("FSymTab$z")) const struct finsh_syscall __fsym_end =
{
__fsym_end_name,
__fsym_end_desc,
NULL
};
#endif
/*
* @ingroup finsh
*
* This function will initialize finsh shell
*/
int finsh_system_init(void)
{
rt_err_t result = RT_EOK;
rt_thread_t tid;
#ifdef FINSH_USING_SYMTAB
#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM C Compiler */
extern const int FSymTab$$Base;
extern const int FSymTab$$Limit;
extern const int VSymTab$$Base;
extern const int VSymTab$$Limit;
finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
#ifndef FINSH_USING_MSH_ONLY
finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
#endif
#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
finsh_system_function_init(__section_begin("FSymTab"),
__section_end("FSymTab"));
finsh_system_var_init(__section_begin("VSymTab"),
__section_end("VSymTab"));
#elif defined (__GNUC__) || defined(__TI_COMPILER_VERSION__)
/* GNU GCC Compiler and TI CCS */
extern const int __fsymtab_start;
extern const int __fsymtab_end;
extern const int __vsymtab_start;
extern const int __vsymtab_end;
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(_MSC_VER)
unsigned int *ptr_begin, *ptr_end;
if(shell)
{
rt_kprintf("finsh shell already init.\n");
return RT_EOK;
}
ptr_begin = (unsigned int *)&__fsym_begin;
ptr_begin += (sizeof(struct finsh_syscall) / sizeof(unsigned int));
while (*ptr_begin == 0) ptr_begin ++;
ptr_end = (unsigned int *) &__fsym_end;
ptr_end --;
while (*ptr_end == 0) ptr_end --;
finsh_system_function_init(ptr_begin, ptr_end);
#endif
#endif
#ifdef RT_USING_HEAP
/* create or set shell structure */
shell = (struct finsh_shell *)rt_calloc(1, sizeof(struct finsh_shell));
if (shell == RT_NULL)
{
rt_kprintf("no memory for shell\n");
return -1;
}
tid = rt_thread_create(FINSH_THREAD_NAME,
finsh_thread_entry, RT_NULL,
FINSH_THREAD_STACK_SIZE, FINSH_THREAD_PRIORITY, 10);
#else
shell = &_shell;
tid = &finsh_thread;
result = rt_thread_init(&finsh_thread,
FINSH_THREAD_NAME,
finsh_thread_entry, RT_NULL,
&finsh_thread_stack[0], sizeof(finsh_thread_stack),
FINSH_THREAD_PRIORITY, 10);
#endif /* RT_USING_HEAP */
rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
finsh_set_prompt_mode(1);
if (tid != NULL && result == RT_EOK)
rt_thread_startup(tid);
return 0;
}
INIT_APP_EXPORT(finsh_system_init);
#endif /* RT_USING_FINSH */

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-06-02 Bernard Add finsh_get_prompt function declaration
*/
#ifndef __SHELL_H__
#define __SHELL_H__
#include <rtthread.h>
#include "finsh.h"
#ifndef FINSH_THREAD_PRIORITY
#define FINSH_THREAD_PRIORITY 20
#endif
#ifndef FINSH_THREAD_STACK_SIZE
#define FINSH_THREAD_STACK_SIZE 2048
#endif
#ifndef FINSH_CMD_SIZE
#define FINSH_CMD_SIZE 80
#endif
#define FINSH_OPTION_ECHO 0x01
#define FINSH_PROMPT finsh_get_prompt()
const char* finsh_get_prompt(void);
int finsh_set_prompt(const char * prompt);
#ifdef FINSH_USING_HISTORY
#ifndef FINSH_HISTORY_LINES
#define FINSH_HISTORY_LINES 5
#endif
#endif
#ifdef FINSH_USING_AUTH
#ifndef FINSH_PASSWORD_MAX
#define FINSH_PASSWORD_MAX RT_NAME_MAX
#endif
#ifndef FINSH_PASSWORD_MIN
#define FINSH_PASSWORD_MIN 6
#endif
#ifndef FINSH_DEFAULT_PASSWORD
#define FINSH_DEFAULT_PASSWORD "rtthread"
#endif
#endif /* FINSH_USING_AUTH */
#ifndef FINSH_THREAD_NAME
#define FINSH_THREAD_NAME "tshell"
#endif
enum input_stat
{
WAIT_NORMAL,
WAIT_SPEC_KEY,
WAIT_FUNC_KEY,
};
struct finsh_shell
{
struct rt_semaphore rx_sem;
enum input_stat stat;
rt_uint8_t echo_mode:1;
rt_uint8_t prompt_mode: 1;
#ifdef FINSH_USING_HISTORY
rt_uint16_t current_history;
rt_uint16_t history_count;
char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE];
#endif
#ifndef FINSH_USING_MSH_ONLY
struct finsh_parser parser;
#endif
char line[FINSH_CMD_SIZE];
rt_uint16_t line_position;
rt_uint16_t line_curpos;
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
rt_device_t device;
#endif
#ifdef FINSH_USING_AUTH
char password[FINSH_PASSWORD_MAX];
#endif
};
void finsh_set_echo(rt_uint32_t echo);
rt_uint32_t finsh_get_echo(void);
int finsh_system_init(void);
void finsh_set_device(const char* device_name);
const char* finsh_get_device(void);
rt_uint32_t finsh_get_prompt_mode(void);
void finsh_set_prompt_mode(rt_uint32_t prompt_mode);
#ifdef FINSH_USING_AUTH
rt_err_t finsh_set_password(const char *password);
const char *finsh_get_password(void);
#endif
#endif

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef LIBC_DIRENT_H__
#define LIBC_DIRENT_H__
#define DT_UNKNOWN 0x00
#define DT_REG 0x01
#define DT_DIR 0x02
#endif

View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016-11-12 Bernard The first version
*/
#ifndef LIBC_ERRNO_H__
#define LIBC_ERRNO_H__
#include <rtconfig.h>
#if defined(RT_USING_NEWLIB) || defined(_WIN32)
/* use errno.h file in toolchains */
#include <errno.h>
#endif
#if defined(__CC_ARM)
/*
defined in armcc/errno.h
#define EDOM 1
#define ERANGE 2
#define EILSEQ 4
#define ESIGNUM 3
#define EINVAL 5
#define ENOMEM 6
*/
#define ERROR_BASE_NO 7
#elif defined(__IAR_SYSTEMS_ICC__)
/* defined in iar/errno.h
#define EDOM 33
#define ERANGE 34
#define EFPOS 35
#define EILSEQ 36
*/
#define ERROR_BASE_NO 36
#else
#define ERROR_BASE_NO 0
#endif
#if !defined(RT_USING_NEWLIB) && !defined(_WIN32)
#define EPERM (ERROR_BASE_NO + 1)
#define ENOENT (ERROR_BASE_NO + 2)
#define ESRCH (ERROR_BASE_NO + 3)
#define EINTR (ERROR_BASE_NO + 4)
#define EIO (ERROR_BASE_NO + 5)
#define ENXIO (ERROR_BASE_NO + 6)
#define E2BIG (ERROR_BASE_NO + 7)
#define ENOEXEC (ERROR_BASE_NO + 8)
#define EBADF (ERROR_BASE_NO + 9)
#define ECHILD (ERROR_BASE_NO + 10)
#define EAGAIN (ERROR_BASE_NO + 11)
#ifndef ENOMEM
#define ENOMEM (ERROR_BASE_NO + 12)
#endif
#define EACCES (ERROR_BASE_NO + 13)
#define EFAULT (ERROR_BASE_NO + 14)
#define ENOTBLK (ERROR_BASE_NO + 15)
#define EBUSY (ERROR_BASE_NO + 16)
#define EEXIST (ERROR_BASE_NO + 17)
#define EXDEV (ERROR_BASE_NO + 18)
#define ENODEV (ERROR_BASE_NO + 19)
#define ENOTDIR (ERROR_BASE_NO + 20)
#define EISDIR (ERROR_BASE_NO + 21)
#ifndef EINVAL
#define EINVAL (ERROR_BASE_NO + 22)
#endif
#define ENFILE (ERROR_BASE_NO + 23)
#define EMFILE (ERROR_BASE_NO + 24)
#define ENOTTY (ERROR_BASE_NO + 25)
#define ETXTBSY (ERROR_BASE_NO + 26)
#define EFBIG (ERROR_BASE_NO + 27)
#define ENOSPC (ERROR_BASE_NO + 28)
#define ESPIPE (ERROR_BASE_NO + 29)
#define EROFS (ERROR_BASE_NO + 30)
#define EMLINK (ERROR_BASE_NO + 31)
#define EPIPE (ERROR_BASE_NO + 32)
#ifndef EDOM
#define EDOM (ERROR_BASE_NO + 33)
#endif
#ifndef ERANGE
#define ERANGE (ERROR_BASE_NO + 34)
#endif
#define EDEADLK (ERROR_BASE_NO + 35)
#define ENAMETOOLONG (ERROR_BASE_NO + 36)
#define ENOLCK (ERROR_BASE_NO + 37)
#define ENOSYS (ERROR_BASE_NO + 38)
#define ENOTEMPTY (ERROR_BASE_NO + 39)
#define ELOOP (ERROR_BASE_NO + 40)
#define EWOULDBLOCK EAGAIN
#define ENOMSG (ERROR_BASE_NO + 42)
#define EIDRM (ERROR_BASE_NO + 43)
#define ECHRNG (ERROR_BASE_NO + 44)
#define EL2NSYNC (ERROR_BASE_NO + 45)
#define EL3HLT (ERROR_BASE_NO + 46)
#define EL3RST (ERROR_BASE_NO + 47)
#define ELNRNG (ERROR_BASE_NO + 48)
#define EUNATCH (ERROR_BASE_NO + 49)
#define ENOCSI (ERROR_BASE_NO + 50)
#define EL2HLT (ERROR_BASE_NO + 51)
#define EBADE (ERROR_BASE_NO + 52)
#define EBADR (ERROR_BASE_NO + 53)
#define EXFULL (ERROR_BASE_NO + 54)
#define ENOANO (ERROR_BASE_NO + 55)
#define EBADRQC (ERROR_BASE_NO + 56)
#define EBADSLT (ERROR_BASE_NO + 57)
#define EDEADLOCK EDEADLK
#define EBFONT (ERROR_BASE_NO + 59)
#define ENOSTR (ERROR_BASE_NO + 60)
#define ENODATA (ERROR_BASE_NO + 61)
#define ETIME (ERROR_BASE_NO + 62)
#define ENOSR (ERROR_BASE_NO + 63)
#define ENONET (ERROR_BASE_NO + 64)
#define ENOPKG (ERROR_BASE_NO + 65)
#define EREMOTE (ERROR_BASE_NO + 66)
#define ENOLINK (ERROR_BASE_NO + 67)
#define EADV (ERROR_BASE_NO + 68)
#define ESRMNT (ERROR_BASE_NO + 69)
#define ECOMM (ERROR_BASE_NO + 70)
#define EPROTO (ERROR_BASE_NO + 71)
#define EMULTIHOP (ERROR_BASE_NO + 72)
#define EDOTDOT (ERROR_BASE_NO + 73)
#define EBADMSG (ERROR_BASE_NO + 74)
#define EOVERFLOW (ERROR_BASE_NO + 75)
#define ENOTUNIQ (ERROR_BASE_NO + 76)
#define EBADFD (ERROR_BASE_NO + 77)
#define EREMCHG (ERROR_BASE_NO + 78)
#define ELIBACC (ERROR_BASE_NO + 79)
#define ELIBBAD (ERROR_BASE_NO + 80)
#define ELIBSCN (ERROR_BASE_NO + 81)
#define ELIBMAX (ERROR_BASE_NO + 82)
#define ELIBEXEC (ERROR_BASE_NO + 83)
#ifndef EILSEQ
#define EILSEQ (ERROR_BASE_NO + 84)
#endif
#define ERESTART (ERROR_BASE_NO + 85)
#define ESTRPIPE (ERROR_BASE_NO + 86)
#define EUSERS (ERROR_BASE_NO + 87)
#define ENOTSOCK (ERROR_BASE_NO + 88)
#define EDESTADDRREQ (ERROR_BASE_NO + 89)
#define EMSGSIZE (ERROR_BASE_NO + 90)
#define EPROTOTYPE (ERROR_BASE_NO + 91)
#define ENOPROTOOPT (ERROR_BASE_NO + 92)
#define EPROTONOSUPPORT (ERROR_BASE_NO + 93)
#define ESOCKTNOSUPPORT (ERROR_BASE_NO + 94)
#define EOPNOTSUPP (ERROR_BASE_NO + 95)
#define ENOTSUP EOPNOTSUPP
#define EPFNOSUPPORT (ERROR_BASE_NO + 96)
#define EAFNOSUPPORT (ERROR_BASE_NO + 97)
#define EADDRINUSE (ERROR_BASE_NO + 98)
#define EADDRNOTAVAIL (ERROR_BASE_NO + 99)
#define ENETDOWN (ERROR_BASE_NO + 100)
#define ENETUNREACH (ERROR_BASE_NO + 101)
#define ENETRESET (ERROR_BASE_NO + 102)
#define ECONNABORTED (ERROR_BASE_NO + 103)
#define ECONNRESET (ERROR_BASE_NO + 104)
#define ENOBUFS (ERROR_BASE_NO + 105)
#define EISCONN (ERROR_BASE_NO + 106)
#define ENOTCONN (ERROR_BASE_NO + 107)
#define ESHUTDOWN (ERROR_BASE_NO + 108)
#define ETOOMANYREFS (ERROR_BASE_NO + 109)
#define ETIMEDOUT (ERROR_BASE_NO + 110)
#define ECONNREFUSED (ERROR_BASE_NO + 111)
#define EHOSTDOWN (ERROR_BASE_NO + 112)
#define EHOSTUNREACH (ERROR_BASE_NO + 113)
#define EALREADY (ERROR_BASE_NO + 114)
#define EINPROGRESS (ERROR_BASE_NO + 115)
#define ESTALE (ERROR_BASE_NO + 116)
#define EUCLEAN (ERROR_BASE_NO + 117)
#define ENOTNAM (ERROR_BASE_NO + 118)
#define ENAVAIL (ERROR_BASE_NO + 119)
#define EISNAM (ERROR_BASE_NO + 120)
#define EREMOTEIO (ERROR_BASE_NO + 121)
#define EDQUOT (ERROR_BASE_NO + 122)
#define ENOMEDIUM (ERROR_BASE_NO + 123)
#define EMEDIUMTYPE (ERROR_BASE_NO + 124)
#define ECANCELED (ERROR_BASE_NO + 125)
#define ENOKEY (ERROR_BASE_NO + 126)
#define EKEYEXPIRED (ERROR_BASE_NO + 127)
#define EKEYREVOKED (ERROR_BASE_NO + 128)
#define EKEYREJECTED (ERROR_BASE_NO + 129)
#define EOWNERDEAD (ERROR_BASE_NO + 130)
#define ENOTRECOVERABLE (ERROR_BASE_NO + 131)
#define ERFKILL (ERROR_BASE_NO + 132)
#define EHWPOISON (ERROR_BASE_NO + 133)
#endif
#endif

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* File : libc_fcntl.h
*
* Change Logs:
* Date Author Notes
* 2018-02-07 Bernard Add O_DIRECTORY definition in NEWLIB mode.
* 2018-02-09 Bernard Add O_BINARY definition
*/
#ifndef LIBC_FCNTL_H__
#define LIBC_FCNTL_H__
#if defined(RT_USING_NEWLIB) || defined(_WIN32)
#include <fcntl.h>
#ifndef O_NONBLOCK
#define O_NONBLOCK 0x4000
#endif
#if defined(_WIN32)
#define O_ACCMODE (_O_RDONLY | _O_WRONLY | _O_RDWR)
#endif
#ifndef F_GETFL
#define F_GETFL 3
#endif
#ifndef F_SETFL
#define F_SETFL 4
#endif
#ifndef O_DIRECTORY
#define O_DIRECTORY 0x200000
#endif
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif
#endif
#else
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100
#define O_EXCL 0200
#define O_NOCTTY 0400
#define O_TRUNC 01000
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_DSYNC 010000
#define O_SYNC 04010000
#define O_RSYNC 04010000
#define O_BINARY 0100000
#define O_DIRECTORY 0200000
#define O_NOFOLLOW 0400000
#define O_CLOEXEC 02000000
#define O_ASYNC 020000
#define O_DIRECT 040000
#define O_LARGEFILE 0100000
#define O_NOATIME 01000000
#define O_PATH 010000000
#define O_TMPFILE 020200000
#define O_NDELAY O_NONBLOCK
#define O_SEARCH O_PATH
#define O_EXEC O_PATH
#define O_ACCMODE (03|O_SEARCH)
#define F_DUPFD 0
#define F_GETFD 1
#define F_SETFD 2
#define F_GETFL 3
#define F_SETFL 4
#define F_SETOWN 8
#define F_GETOWN 9
#define F_SETSIG 10
#define F_GETSIG 11
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16
#define F_GETOWNER_UIDS 17
#endif
#endif

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* File : libc_errno.h
*
* Change Logs:
* Date Author Notes
* 2017-10-30 Bernard The first version
*/
#ifndef LIBC_FDSET_H__
#define LIBC_FDSET_H__
#include <rtconfig.h>
#if defined(RT_USING_NEWLIB) || defined(_WIN32)
#include <sys/types.h>
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
#endif
#else
#ifdef SAL_USING_POSIX
#ifdef FD_SETSIZE
#undef FD_SETSIZE
#endif
#define FD_SETSIZE DFS_FD_MAX
#endif
# ifndef FD_SETSIZE
# define FD_SETSIZE 32
# endif
# define NBBY 8 /* number of bits in a byte */
typedef long fd_mask;
# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
# ifndef howmany
# define howmany(x,y) (((x)+((y)-1))/(y))
# endif
/* We use a macro for fd_set so that including Sockets.h afterwards
can work. */
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
# define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
#endif
#endif

View File

@ -0,0 +1,234 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* File : libc_ioctl.h
*
* Change Logs:
* Date Author Notes
* 2017-01-21 Bernard the first version
*/
#ifndef LIBC_IOCTL_H__
#define LIBC_IOCTL_H__
#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
#define _IOC_NONE 0U
#define _IOC_WRITE 1U
#define _IOC_READ 2U
#ifndef _WIN32
#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
#define FIONWRITE _IOR('f', 121, int) /* get # bytes outstanding
* in send queue. */
#endif
#define TCGETS 0x5401
#define TCSETS 0x5402
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TCGETA 0x5405
#define TCSETA 0x5406
#define TCSETAW 0x5407
#define TCSETAF 0x5408
#define TCSBRK 0x5409
#define TCXONC 0x540A
#define TCFLSH 0x540B
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCGPGRP 0x540F
#define TIOCSPGRP 0x5410
#define TIOCOUTQ 0x5411
#define TIOCSTI 0x5412
#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
// #define FIONREAD 0x541B
#define TIOCINQ FIONREAD
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
// #define FIONBIO 0x5421
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425
#define TIOCSBRK 0x5427
#define TIOCCBRK 0x5428
#define TIOCGSID 0x5429
#define TIOCGRS485 0x542E
#define TIOCSRS485 0x542F
#define TIOCGPTN 0x80045430
#define TIOCSPTLCK 0x40045431
#define TIOCGDEV 0x80045432
#define TCGETX 0x5432
#define TCSETX 0x5433
#define TCSETXF 0x5434
#define TCSETXW 0x5435
#define TIOCSIG 0x40045436
#define TIOCVHANGUP 0x5437
#define TIOCGPKT 0x80045438
#define TIOCGPTLCK 0x80045439
#define TIOCGEXCL 0x80045440
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
#ifndef _WIN32
#define FIOASYNC 0x5452
#endif
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458
#define TIOCSERGETLSR 0x5459
#define TIOCSERGETMULTI 0x545A
#define TIOCSERSETMULTI 0x545B
#define TIOCMIWAIT 0x545C
#define TIOCGICOUNT 0x545D
#define FIOQSIZE 0x5460
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1
#define TIOCPKT_FLUSHWRITE 2
#define TIOCPKT_STOP 4
#define TIOCPKT_START 8
#define TIOCPKT_NOSTOP 16
#define TIOCPKT_DOSTOP 32
#define TIOCPKT_IOCTL 64
#define TIOCSER_TEMT 0x01
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
};
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_ST 0x008
#define TIOCM_SR 0x010
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
#define N_TTY 0
#define N_SLIP 1
#define N_MOUSE 2
#define N_PPP 3
#define N_STRIP 4
#define N_AX25 5
#define N_X25 6
#define N_6PACK 7
#define N_MASC 8
#define N_R3964 9
#define N_PROFIBUS_FDL 10
#define N_IRDA 11
#define N_SMSBLOCK 12
#define N_HDLC 13
#define N_SYNC_PPP 14
#define N_HCI 15
#define FIOSETOWN 0x8901
#define SIOCSPGRP 0x8902
#define FIOGETOWN 0x8903
#define SIOCGPGRP 0x8904
// #define SIOCATMARK 0x8905
#define SIOCGSTAMP 0x8906
#define SIOCGSTAMPNS 0x8907
#define SIOCADDRT 0x890B
#define SIOCDELRT 0x890C
#define SIOCRTMSG 0x890D
#define SIOCGIFNAME 0x8910
#define SIOCSIFLINK 0x8911
#define SIOCGIFCONF 0x8912
#define SIOCGIFFLAGS 0x8913
#define SIOCSIFFLAGS 0x8914
#define SIOCGIFADDR 0x8915
#define SIOCSIFADDR 0x8916
#define SIOCGIFDSTADDR 0x8917
#define SIOCSIFDSTADDR 0x8918
#define SIOCGIFBRDADDR 0x8919
#define SIOCSIFBRDADDR 0x891a
#define SIOCGIFNETMASK 0x891b
#define SIOCSIFNETMASK 0x891c
#define SIOCGIFMETRIC 0x891d
#define SIOCSIFMETRIC 0x891e
#define SIOCGIFMEM 0x891f
#define SIOCSIFMEM 0x8920
#define SIOCGIFMTU 0x8921
#define SIOCSIFMTU 0x8922
#define SIOCSIFNAME 0x8923
#define SIOCSIFHWADDR 0x8924
#define SIOCGIFENCAP 0x8925
#define SIOCSIFENCAP 0x8926
#define SIOCGIFHWADDR 0x8927
#define SIOCGIFSLAVE 0x8929
#define SIOCSIFSLAVE 0x8930
#define SIOCADDMULTI 0x8931
#define SIOCDELMULTI 0x8932
#define SIOCGIFINDEX 0x8933
#define SIOGIFINDEX SIOCGIFINDEX
#define SIOCSIFPFLAGS 0x8934
#define SIOCGIFPFLAGS 0x8935
#define SIOCDIFADDR 0x8936
#define SIOCSIFHWBROADCAST 0x8937
#define SIOCGIFCOUNT 0x8938
#define SIOCGIFBR 0x8940
#define SIOCSIFBR 0x8941
#define SIOCGIFTXQLEN 0x8942
#define SIOCSIFTXQLEN 0x8943
#define SIOCDARP 0x8953
#define SIOCGARP 0x8954
#define SIOCSARP 0x8955
#define SIOCDRARP 0x8960
#define SIOCGRARP 0x8961
#define SIOCSRARP 0x8962
#define SIOCGIFMAP 0x8970
#define SIOCSIFMAP 0x8971
#define SIOCADDDLCI 0x8980
#define SIOCDELDLCI 0x8981
#define SIOCDEVPRIVATE 0x89F0
#define SIOCPROTOPRIVATE 0x89E0
#endif

Some files were not shown because too many files have changed in this diff Show More