---
# System prepended metadata

title: RISC-V CPU Project

---

# RISC-V CPU Project

## Links

Files:
https://drive.google.com/drive/folders/1dtr3nY3f3Z_RMh9FDAcq3bSkW_cG-gb6?usp=share_link

Github:
https://github.com/Tyan-0978/RISC-V_CPU

## File Architecture

- cpu.v
- inst_memory.v
- inst_dec.v
- reg_file.v
- **alu/**
    - alu.v
    - logic.v
    - int_add_sub.v
    - int_mul.v
    - int_div.v
    - fp_add_sub.v
    - fp_mul.v
    - fp_div.v
- data_memory.v

## 分工

1. 曾
    - 讀 RISC-V spec，整理各個指令的功能
    - 寫 inst_dec.v
2. 陳
    - inst_memory.v
    - data_memory.v
    - reg_file.v
3. 田
    - alu/

## Test
```
addi x11 x0 10
ecall 11
```
00A00593
00058073

```
addi a1 x0 10
addi a2 x0 20
add  a3 a1 a2
ecall a3
```

00A00593
01400613
00C586B3
00061073

```
addi a1 x0 10 # num of iteration
addi a2 x0 0 # index
addi a3 x0 0 # a
addi a4 x0 1 # b
fib:
add  a5 a3 a4
add  a3 a4 x0
add  a4 a5 x0
addi a2 a2 1
bne  a2 a1 fib
ecall a4
```

00A00593
00000613
00000693
00100713
00E687B3
000706B3
00078733
00160613
FEB618E3
00070073

```
addi a1 x0 10
addi a2 x0 0
addi a3 x0 1
addi a4 x0 1
fact:
mul  a4 a3 a4
addi a3 a3 1
addi a2 a2 1
bne  a2 a1 fact
ecall a4
```

```verilog
        0: read_data = 32'h00A00593;
        1: read_data = 32'h00000613;
        2: read_data = 32'h00100693;
        3: read_data = 32'h00100713;
        4: read_data = 32'h02E68733;
        5: read_data = 32'h00168693;
        6: read_data = 32'h00160613;
        7: read_data = 32'hFEB61AE3;
        8: read_data = 32'h00070073;
```

Modulo
```
addi a1 x0 1000
addi a2 x0 0
addi a3 x0 7
addi a4 x0 101
mod:
mul  a3 a3 a3
rem  a3 a3 a4
addi a2 a2 1
bne  a2 a1 mod
ecall a3
```

```verilog
        0: read_data = 32'h3E800593;
        1: read_data = 32'h00000613;
        2: read_data = 32'h00700693;
        3: read_data = 32'h06500713;
        4: read_data = 32'h02D686B3;
        5: read_data = 32'h02E6E6B3;
        6: read_data = 32'h00160613;
        7: read_data = 32'hFEB61AE3;
        8: read_data = 32'h00068073;

```

## ISA 
### RV32I
#### integer
- computational
    - reg-imm
    - reg-reg
    - NOP
         `ADDI x0, x0, 0`
#### control
- unconditional jumps
    - JAL
    - JALR (jump)
- conditional branches
    - BEQ/BNE
    - BLT
    - BGE
#### Load/Store
- LOAD
- STORE
#### memory XXX
- FENCE
    - ![](https://i.imgur.com/o3yvFDr.png)
    - 
- FENCE.I
    - ![](https://i.imgur.com/eTKo2On.png)

#### control & status reg (CSR) XXX
- CSR
- timers & counters
#### environment call 
![](https://i.imgur.com/XJBP7kF.png)
- ECALL
    - request the operating system
- EBREAK
    - give control to the debugging environment
### RV32M

### RV32A　XXX

### RV32F XXX
#### single precision floating point


## I/O Ports

### cpu.v

```verilog
module cpu (
    input  i_rst_n,
    input  i_clk,
    input  i_start,
    // ecall pins
    output o_ecall_ready,
    output [31:0] o_ecall_data
);
```

### reg_file.v

```verilog
module reg_file(
    input  i_rst_n,
    input  i_clk,
    input  i_reg_write,
    input  [ 4:0] i_write_rd,
    input  [31:0] i_write_data,
    input  [ 4:0] i_read_rs1,
    input  [ 4:0] i_read_rs2,
    output [31:0] o_rs1_data,
    output [31:0] o_rs2_data
);
```
### inst_memory.v
nios_system n1(
	.clocks_ref_clk_clk(CLOCK_50),
	.clocks_ref_reset_reset(~KEY[0]),
	.clocks_sdram_clk_clk(DRAM_CLK),
	.sdram_s1_address(address),
	.sdram_s1_byteenable_n(byteenable_n),
	.sdram_s1_chipselect(chipselect),
	.sdram_s1_writedata(writedata),
	.sdram_s1_read_n(read_n),
	.sdram_s1_write_n(write_n),
	.sdram_s1_readdata(readdata),
	.sdram_s1_readdatavalid(readdatavalid),
	.sdram_s1_waitrequest(waitrequest),
	.sdram_wire_addr(DRAM_ADDR),
	.sdram_wire_ba(DRAM_BA),
	.sdram_wire_cas_n(DRAM_CAS_N),
	.sdram_wire_cke(DRAM_CKE),
	.sdram_wire_cs_n(DRAM_CS_N),
	.sdram_wire_dq(DRAM_DQ),
	.sdram_wire_dqm(DRAM_DQM),
	.sdram_wire_ras_n(DRAM_RAS_N),
	.sdram_wire_we_n(DRAM_WE_N)
);


---

### alu/

#### alu

```verilog
module alu (
    input  i_rst_n,
    input  i_clk,
    // control
    input  [ 2:0] i_op_mode,
    input  [ 1:0] i_func_op, // functional options
    input         i_fp_mode, // 0: integer, 1: FP
    input         i_stall,
    output        o_stall,
    // operands & result
    input  [31:0] i_a,
    input  [31:0] i_b,
    output [31:0] o_result
);
```

- `[2:0] i_op_mode`:
    - `0`: idle (do nothing)
    - `1`: logic operation (AND, OR, XOR)
    - `2`: shift operation
    - `3`: comparison
    - `4`: integer addition/subtraction
    - `5`: integer multiplication
    - `6`: integer division
    - `7`: integer modulo operation

:::success
:::spoiler logic

```verilog
module logic (
    input  [1:0]  i_mode, // 0: AND, 1: OR, 2: XOR
    input  [31:0] i_a,
    input  [31:0] i_b,
    output [31:0] o_result
);
```

- type: combinational
- input
    - `[1:0] i_mode`
        - `0`: AND
        - `1`: OR
        - `2`: XOR
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `[31:0] o_result`

:::

:::success
:::spoiler shift

```verilog
module shift (
    input         i_mode, // 0: logical, 1: arithmetic (keep sign)
    input         i_direction, // 0: left, 1: right
    input  signed [31:0] i_a,
    input  signed [31:0] i_b,
    output signed [31:0] o_result
);
```

- type: combinational
- input
    - `i_mode`
        - `0`: logical
        - `1`: arithmetic (keep sign)
    - `i_direction`
        - `0`: left
        - `1`: right
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `[31:0] o_result`

:::

:::success
:::spoiler comp

```verilog
module comp (
    input        i_eq,   // 0: without equal, 1: with equal
    input  [1:0] i_mode, // 00: <, 01: >, 1x: ==
    input  [31:0] i_a,
    input  [31:0] i_b,
    output [31:0] o_result
);
```

- type: combinational
- input
    - `i_eq`
        - `0`: no equal sign (<, >, !=)
        - `1`: with equal sign (<=, >=, ==)
    - `[1:0] i_mode`
        - `00`: smaller than (<)
        - `01`: larger than (>)
        - `1x`: equal (==)
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `[31:0] o_result`

:::

:::success
:::spoiler int_add_sub

```verilog
module int_add_sub (
    input  i_mode, // 0: add, 1: subtract
    input  signed [31:0] i_a,
    input  signed [31:0] i_b,
    output signed [31:0] o_result
);
```

- type: combinational
- input
    - `i_mode`
        - `0`: add
        - `1`: subtract
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `[31:0] o_result`

:::

:::success
:::spoiler int_mul

```verilog
module int_mul (
    input  i_rst_n,
    input  i_clk,
    input  i_valid,
    output o_valid,

    input  signed [31:0] i_a,
    input  signed [31:0] i_b,
    output signed [31:0] o_result
);
```

- type: sequential
- input
    - `i_rst_n`
    - `i_clk`
    - `i_valid`
        - `0`: no input
        - `1`: valid input
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `o_valid`
        - pull to `1` when multiplication finished
    - `[31:0] o_result`

:::

:::success
:::spoiler int_div

```verilog
module int_div (
    input  i_rst_n,
    input  i_clk,
    input  i_valid,
    output o_valid,

    input  signed [31:0] i_a,
    input  signed [31:0] i_b,
    output signed [31:0] o_quotient,
    output signed [31:0] o_remainder
);
```

- type: sequential
- input
    - `i_rst_n`
    - `i_clk`
    - `i_valid`
        - `0`: no input
        - `1`: valid input
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `o_valid`
        - pull to `1` when division finished
    - `[31:0] o_quotient`
    - `[31:0] o_remainder`

:::

:::success
:::spoiler fp_add_sub

```verilog
module int_add_sub (
    input  i_mode, // 0: add, 1: subtract
    input  [31:0] i_a,
    input  [31:0] i_b,
    output [31:0] o_result
);
```

- type: combinational
- input
    - `i_mode`
        - `0`: add
        - `1`: subtract
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `[31:0] o_result`

:::

:::success
:::spoiler fp_mul

```verilog
module fp_mul (
    input  i_rst_n,
    input  i_clk,
    input  i_valid,
    output o_valid,

    input  signed [31:0] i_a,
    input  signed [31:0] i_b,
    output signed [31:0] o_result
);
```

- type: sequential
- input
    - `i_rst_n`
    - `i_clk`
    - `i_valid`
        - `0`: no input
        - `1`: valid input
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `o_valid`
        - pull to `1` when multiplication finished
    - `[31:0] o_result`

:::

:::success
:::spoiler fp_div

```verilog
module fp_div (
    input  i_rst_n,
    input  i_clk,
    input  i_valid,
    output o_valid,

    input  signed [31:0] i_a,
    input  signed [31:0] i_b,
    output signed [31:0] o_result
);
```

- type: sequential
- input
    - `i_rst_n`
    - `i_clk`
    - `i_valid`
        - `0`: no input
        - `1`: valid input
    - `[31:0] i_a`
    - `[31:0] i_b`
- output
    - `o_valid`
        - pull to `1` when division finished
    - `[31:0] o_result`

:::

### inst_dec.v
 - input
    - `[31:0] i_inst_data`
 - output
     - `[4:0] o_rd`
     - `[4:0] o_rs1`
     - `[4:0] o_rs2`
     - `[31:0] o_imm`
     - `[31:0] o_jump_imm`
     - `[2:0] o_funct3`
     - `o_ecall`
     - `o_alusrc`
     - `o_mem_to_reg`
     - `o_reg_write`
     - `o_mem_read`
     - `o_mem_write`
     - `o_branch`
     - `[2:0] o_op_mode`
     - `[2:0] o_func_op`
     - `o_fp_mode`
    