AlibabaのRISC-Vを見る

# AlibabaのRISC-V

7月にAlibabaグループのPingtougeが自社開発のRISC-V「Xuantie 910」をアナウンスしていましたが、
それに関連したRISC-Vデータがgithubで公開されました。

https://github.com/T-head-Semi/wujian100_open

## ライセンス
MIT License
A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.

## スペック
- CPU Part
 - 32-bit general purpose CPU E902
- CoreTim
 - The circulating decrement counter is 24-bit count width
- VIC
 - Supports 64 Interrupts nesting
 - Each interrupt has corresponding priority
- Memory
 - 64KB ISRAM and 3×64KB DSRAM on-chip SRAM
- Characteristics of Peripherals
 - DMAC(x1)
     - 16 channels
     - Supports block/group trigger mode transactions
 - TIM (×8)
     - connects to APB1 and APB0
     - All of timers are 32-bit count width
     - All of timers support for two operation modes: free-running and user-defined count
 - GPIO (×1)
     - Connects to APB
     - GPIO supports 32-bit width;
     - Each bit of GPIO supports interrupt generation
 - USI (×3)
     - Universal Asynchronous Receiver/Transmitter(UART)
     - Inter-integrated Circuit(I2C)
     - Serial Peripheral Interface(SPI)
 - RTC 
     - RTC connects to APB
     - 32-bit count width
     - Incrementing counter and comparator for interrupt generation
 - PWM
     - Connects to APB
     - 12 input/output channels
     - 6 PWM generators, each with 1 32-bit counter, 2 PWM comparator, 1 PWM signal generator, 1 interrupt generator
     - Each PWM signal generator contains 2 channels
     - PWM output enable or disable of each PWM signal
     - Optional output inversion of each PWM signal (polarity control)
     - 6 32-bit counter and each has the following characteristics:
         - Up or Up/Down mode
         - Output frequency controlled by a 16-bit load value
     - 32-bit input capture modes
         - Input edge count mode
         - Input edge time mode
 - WDT
     - One WDT in APB
     - Each WDT has 32 count width
     - Counter counts down from a pre-set value to zero to indicate the occurrence of a timeout


## RTL

### トップモジュール：wujian100_open_top.v (1570行)
wujian100_open/soc/wujian100_open_top.v
Verilogです。SystemVerilogではありません。

/*
Copyright (c) 2019 Alibaba Group Holding Limited

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/
module wujian100_open_top(
  PAD_GPIO_0,
  PAD_GPIO_1,
  PAD_GPIO_10,
  PAD_GPIO_11,
  PAD_GPIO_12,
  PAD_GPIO_13,
  PAD_GPIO_14,
  PAD_GPIO_15,
  PAD_GPIO_16,
  PAD_GPIO_17,
  PAD_GPIO_18,
  PAD_GPIO_19,
  PAD_GPIO_2,
  PAD_GPIO_20,
  PAD_GPIO_21,
  PAD_GPIO_22,
  PAD_GPIO_23,
  PAD_GPIO_24,
  PAD_GPIO_25,
  PAD_GPIO_26,
  PAD_GPIO_27,
  PAD_GPIO_28,
  PAD_GPIO_29,
  PAD_GPIO_3,
(省略)


### CPUコア：E902_20191018.v (23,436行)
\`define PRODUCT_ID 16'h0000
\`define RESET_VAL 16'hABCD
\`define GATED_CELL
\`define SMIC
\`define PROCESS55LL
\`ifdef USER_MODE
  \`define MACHINE_SP
\`endif
\`define CLIC_MODE
\`ifdef CSKY_TEE
  \`define USER_MODE
  \`define MACHINE_SP
\`endif
\`define GPR_16
\`define VEC_BASE
\`define LOAD_FAST_RETIRE
\`define WB_LOAD_FWD_TO_EX
\`define MAD_SMALL
\`define IAHB_LITE
\`ifdef IAHB_LITE
  \`define IBUS_32
\`endif
\`ifdef DAHB_LITE
  \`define DBUS_32
\`endif
\`define SYS_AHB_LITE
\`define BIU_32
\`ifdef FLOP_OUT_BIU
\`define FLOP_OUT_BUS
\`else
  \`ifdef FLOP_OUT_IBUS
  \`define FLOP_OUT_BUS
  \`else
    \`ifdef FLOP_OUT_DBUS
・・・中略
//デコードのあたり
assign decd_mad_sel         = decd_op[6:0] == 7'b0110011 && decd_func7[0] &&
                              !decd_inst_expt;
assign decd_mad_inst_mul    = decd_mad_sel && decd_func3[2:0] == 3'b000; 
assign decd_mad_inst_mulh   = decd_mad_sel && decd_func3[2:0] == 3'b001; 
assign decd_mad_inst_mulhsu = decd_mad_sel && decd_func3[2:0] == 3'b010; 
assign decd_mad_inst_mulhu  = decd_mad_sel && decd_func3[2:0] == 3'b011; 
assign decd_mad_inst_div    = decd_mad_sel && decd_func3[2:0] == 3'b100; 
assign decd_mad_inst_divu   = decd_mad_sel && decd_func3[2:0] == 3'b101; 
assign decd_mad_inst_rem    = decd_mad_sel && decd_func3[2:0] == 3'b110; 
assign decd_mad_inst_remu   = decd_mad_sel && decd_func3[2:0] == 3'b111; 
assign decd_lsu_sel   = (decd_inst_clwsp || decd_inst_cswsp || decd_inst_clw   
                      || decd_inst_csw   || decd_inst_lb    || decd_inst_lh
                      || decd_inst_lbu   || decd_inst_lhu   || decd_inst_lw
                      || decd_inst_sb    || decd_inst_sh    || decd_inst_sw
                      || decd_inst_fence || decd_inst_fencei)
                      && !decd_inst_expt;
assign decd_inst_clwsp = decd_op[4:0] == 5'b01010;
assign decd_inst_cswsp = decd_op[4:0] == 5'b11010;
assign decd_inst_clw   = decd_op[4:0] == 5'b01000;
assign decd_inst_csw   = decd_op[4:0] == 5'b11000;
assign decd_inst_lb    = decd_op[6:0] == 7'b0000011 && decd_func3[2:0] == 3'b000; 
assign decd_inst_lh    = decd_op[6:0] == 7'b0000011 && decd_func3[2:0] == 3'b001; 
assign decd_inst_lw    = decd_op[6:0] == 7'b0000011 && decd_func3[2:0] == 3'b010; 
assign decd_inst_lbu   = decd_op[6:0] == 7'b0000011 && decd_func3[2:0] == 3'b100; 
assign decd_inst_lhu   = decd_op[6:0] == 7'b0000011 && decd_func3[2:0] == 3'b101; 
assign decd_inst_sb    = decd_op[6:0] == 7'b0100011 && decd_func3[2:0] == 3'b000; 
assign decd_inst_sh    = decd_op[6:0] == 7'b0100011 && decd_func3[2:0] == 3'b001; 
assign decd_inst_sw    = decd_op[6:0] == 7'b0100011 && decd_func3[2:0] == 3'b010; 
assign decd_lsu_store  = decd_inst_cswsp || decd_inst_csw || decd_inst_sb
                      || decd_inst_sh    || decd_inst_sw;
assign decd_lsu_byte   = decd_inst_lb    || decd_inst_lbu || decd_inst_sb;
assign decd_lsu_half   = decd_inst_lh    || decd_inst_lhu || decd_inst_sh;
assign decd_lsu_uns    = decd_inst_lbu   || decd_inst_lhu;
assign decd_inst_fence  = decd_op[6:0] == 7'b0001111 && !decd_func3[0];
assign decd_inst_fencei = decd_op[6:0] == 7'b0001111 &&  decd_func3[0];
assign decd_sys         = decd_op[6:0] == 7'b1110011 
                      && !decd_inst_expt;
assign decd_inst_ecall  = decd_sys && decd_func3[2:0] == 3'b000 && decd_rs2[1:0] == 2'b0;
assign decd_inst_mret   = decd_sys && decd_func3[2:0] == 3'b000 && decd_rs2[1];
assign decd_inst_mret_nor= decd_inst_mret && (cp0_yy_priv_mode[1:0] == 2'b11);
(省略)


ニュースでは50の拡張命令があると言ってましたが、さすがにgithubの内容には含まれてなさそうです。
ドキュメントには、TIM, DMA, USI, WDT, PWM, RTC, GPIO の機能が記載されています。

## FPGA
Xilinx Artix-7 XC7A200T-FGG484用のVivadoプロジェクトが用意されています。


# まとめ
中国の勢いは凄い。