Skip to content
This repository has been archived by the owner on Aug 22, 2023. It is now read-only.

Commit

Permalink
docs&refactor: README, docs and optimized code
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingfish404 committed Nov 9, 2022
1 parent 5ddc806 commit bdb068f
Show file tree
Hide file tree
Showing 11 changed files with 1,384 additions and 1,122 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# RISC-V (Sub-Set) Out-of-Order Interpreter

![](public/demo.png)

## Getting Started

```bash
Expand All @@ -9,10 +11,21 @@ npm run dev # or `yarn dev`
npm test # or `yarn test`
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. [Docs](docs/README.md).

## TODO

- [ ] Add more instructions
- [ ] Add Decode Stage and Memory Stage
- [ ] HCI optimization

## Technical Stack

- core: typescript
- ui: next.js && react.js && antd && sass && mdx-js
- test: jest && ts-jest
- compability: core-js


## License

MIT License
11 changes: 11 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
## Docs

### CPU and Pipeline

[risc-v core-code](/src/utils/rsic-v/index.ts)

Pipline:
- IF: Instruction Fetch
- EX: Execution
- WB: Write Back

### Supported Instructions

`ADD` rd, rs1, rs2
`ADDI` rd, rs1, imm
`SUB` rd, rs1, rs2

`JAL` rd, imm

`FLD` rd, imm(rs1) : rd <- MEM[rs1+imm]
`FSD` rs2, imm(rs1) : MEM[rs1+imm] <- rs2

Expand Down
21 changes: 11 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,22 @@
"dependencies": {
"@mdx-js/loader": "^2.1.5",
"@mdx-js/react": "^2.1.5",
"@next/mdx": "^12.3.1",
"antd": "^4.23.6",
"@next/mdx": "^13.0.2",
"@uiw/react-codemirror": "^4.13.0",
"antd": "^4.24.1",
"core-js": "^3.26.0",
"next": "12.3.1",
"next": "13.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"sass": "^1.55.0"
"sass": "^1.56.1"
},
"devDependencies": {
"@types/node": "18.11.3",
"@types/react": "18.0.21",
"@types/react-dom": "18.0.6",
"eslint": "8.25.0",
"eslint-config-next": "12.3.1",
"jest": "^29.2.1",
"@types/node": "18.11.9",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.8",
"eslint": "8.27.0",
"eslint-config-next": "13.0.2",
"jest": "^29.3.1",
"ts-jest": "^29.0.3",
"typescript": "4.8.4"
}
Expand Down
Binary file added public/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/pages/docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function Page() {
</Head>
<header>
<Space>
<Link href="/"><a className={styles.title}>{title}</a></Link>
<Link href="/" className={styles.title}>{title}</Link>
<Link href="/docs"><Button type='link' >Docs</Button></Link>
</Space>
</header>
Expand Down
22 changes: 11 additions & 11 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { NextPage } from 'next'
import Head from 'next/head'
import { SetStateAction, useState } from 'react'
import { useState, useCallback } from 'react'
import { Input, Button, Space } from 'antd';
import CodeMirror from '@uiw/react-codemirror';
import { ViewUpdate } from '@codemirror/view';
import 'core-js/actual/structured-clone';
import { EditableTable } from '../components';
import {
Expand Down Expand Up @@ -36,37 +38,35 @@ const Home: NextPage = () => {
</Head>
<header>
<Space>
<Link href="/"><a className={styles.title}>{title}</a></Link>
<Link href="/" className={styles.title}>{title}</Link>
<Link href="/docs"><Button type='link' >Docs</Button></Link>
</Space>
</header>
<main className={styles.main}>
<div className={styles.grid}>
<div className={styles.grid_item}>
<h2>Code place</h2>
<TextArea
style={{ width: '100%', height: '100%', fontFamily: 'monospace' }}
<CodeMirror
value={code}
onChange={(e: { target: { value: string; }; }) => {
const value = e.target.value;
className={styles.code}
maxHeight={'300px'}
onChange={useCallback((value: string, viewUpdate: ViewUpdate) => {
setCode(value);
setInterpreter(new Interpreter(value));
while (history.length > 0) {
history.pop();
};
}}
placeholder="ASM code"
autoSize={{ minRows: 10, maxRows: 10 }}
}, [history])}
/>
<hr />
<Space >
<Button onClick={
() => {
const last_state = structuredClone(interpreter);
let last_state = structuredClone(interpreter);
while (interpreter.step() == 0) {
if (interpreter.cycle === last_state.cycle + 1) {
history.push(last_state);
}
last_state = structuredClone(interpreter);
}
setReload(!reload);
}
Expand Down
6 changes: 5 additions & 1 deletion src/styles/Home.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
}
}

.code {
margin: 0 0 1rem 0;
}

.grid {
p {
margin: 0.25em 0;
Expand All @@ -29,12 +33,12 @@
display: inline-block;
padding: 1rem;
border: 1px solid #eaeaea;
overflow: auto;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: color 0.15s ease, border-color 0.15s ease;
min-height: 200px;
max-height: 500px;
overflow: auto;
}
}

Expand Down
80 changes: 37 additions & 43 deletions src/utils/rsic-v/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IntegerRegister, FloatingPointRegister } from "./hardware";

import { RV64I, RV64D } from "./isa";

export enum InstructionStage {
IF = 'IF',
Expand Down Expand Up @@ -108,15 +108,11 @@ export class Interpreter {
this.x_register[rd] = this.x_register[rs1] - this.x_register[rs2];
}

subi(rd: keyof IntegerRegister,
rs1: keyof IntegerRegister,
imm: number) {
if (rd == 'x0') {
return;
jal(rd: keyof IntegerRegister, imm: number) {
if (rd != 'x0') {
this.x_register[rd] = this.pc + 4;
}
imm = this.normalizeImm(imm);
imm = this.immPad(imm);
this.x_register[rd] = this.x_register[rs1] - imm;
this.pc = imm;
}

fld(rd: keyof FloatingPointRegister, imm: number, rs1: keyof IntegerRegister) {
Expand Down Expand Up @@ -191,8 +187,8 @@ export class Interpreter {
let can_fetch = false;
let station: Station = { name: '', busy: false, op: '', v: 0, qi: '', qj: '', qk: '' }
switch (op) {
case 'fsd':
case 'fld':
case RV64D.FSD:
case RV64D.FLD:
for (let cur_station of this.reservation_station
.filter((station) => station.busy == false && station.name.startsWith('load'))) {
cur_station.a = tokens[1] as string;
Expand All @@ -201,19 +197,19 @@ export class Interpreter {
break
}
break
case 'fmul':
case 'fdiv':
case RV64D.FADD:
case RV64D.FSUB:
for (let cur_station of this.reservation_station
.filter((station) => station.busy == false && station.name.startsWith('fmul'))) {
.filter((station) => station.busy == false && station.name.startsWith('fadd'))) {
can_fetch = true;
station = cur_station;
break;
}
break
case 'fsub':
case 'fadd':
case RV64D.FMUL:
case RV64D.FDIV:
for (let cur_station of this.reservation_station
.filter((station) => station.busy == false && station.name.startsWith('fadd'))) {
.filter((station) => station.busy == false && station.name.startsWith('fmul'))) {
can_fetch = true;
station = cur_station;
break;
Expand All @@ -223,7 +219,7 @@ export class Interpreter {
can_fetch = true;
break
}
if (can_fetch) {
if (can_fetch && this.pipeline.find((unit) => unit.op == 'jal') == undefined) {
this.log.push('Fetch: ' + instruction + ', PC: ' + this.pc);
for (let i = 0; i < tokens.length; i++) {
if (typeof tokens[i] != 'string') {
Expand Down Expand Up @@ -283,18 +279,18 @@ export class Interpreter {
&& (unit.station.qk == unit.station.name || unit.station.qk === '')) {
unit.EX_S = this.cycle;
switch (op) {
case 'fld':
case 'fsd':
case RV64D.FSD:
case RV64D.FLD:
unit.C_need = 2;
break
case 'fadd':
case 'fsub':
case RV64D.FADD:
case RV64D.FSUB:
unit.C_need = 2;
break
case 'fmul':
case RV64D.FMUL:
unit.C_need = 10;
break
case 'fdiv':
case RV64D.FDIV:
unit.C_need = 40;
break
default:
Expand All @@ -320,33 +316,31 @@ export class Interpreter {
}
const { op, tokens } = unit;
switch (op) {
case 'add':
case RV64I.ADD:
this.add(tokens[0] as keyof IntegerRegister,
tokens[1] as keyof IntegerRegister,
tokens[2] as keyof IntegerRegister);
break;
case 'addi':
case RV64I.ADDI:
if (typeof tokens[2] != 'number') {
throw new Error("ADDI: Immediate is not a number");
}
this.addi(tokens[0] as keyof IntegerRegister,
tokens[1] as keyof IntegerRegister,
tokens[2]);
break;
case 'sub':
case RV64I.SUB:
this.sub(tokens[0] as keyof IntegerRegister,
tokens[1] as keyof IntegerRegister,
tokens[2] as keyof IntegerRegister);
break;
case 'subi':
if (typeof tokens[2] != 'number') {
throw new Error("SUBI: Immediate is not a number");
case RV64I.JAL:
if (typeof tokens[1] != 'number') {
throw new Error("JAL: Immediate is not a number");
}
this.subi(tokens[0] as keyof IntegerRegister,
tokens[1] as keyof IntegerRegister,
tokens[2]);
this.jal(tokens[0], tokens[1]);
break;
case 'fld':
case RV64D.FLD:
const address = tokens[1] as string;
const imm = parseInt(address.split('(')[0]);
const rs1 = address.split('(')[1].split(')')[0];
Expand All @@ -356,34 +350,34 @@ export class Interpreter {
unit.station.v = this.f_register[tokens[0] as keyof FloatingPointRegister];
unit.station.a = ''
break;
case 'fsd':
case RV64D.FSD:
const address2 = tokens[1] as string;
const imm2 = parseInt(address2.split('(')[0]);
const rs12 = address2.split('(')[1].split(')')[0];
this.fsd(tokens[0] as keyof FloatingPointRegister,
imm2,
rs12 as keyof IntegerRegister);
break;
case 'fmul':
this.fmul(tokens[0] as keyof FloatingPointRegister,
case RV64D.FADD:
this.fadd(tokens[0] as keyof FloatingPointRegister,
tokens[1] as keyof FloatingPointRegister,
tokens[2] as keyof FloatingPointRegister);
unit.station.v = this.f_register[tokens[0] as keyof FloatingPointRegister];
break;
case 'fdiv':
this.fdiv(tokens[0] as keyof FloatingPointRegister,
case RV64D.FSUB:
this.fsub(tokens[0] as keyof FloatingPointRegister,
tokens[1] as keyof FloatingPointRegister,
tokens[2] as keyof FloatingPointRegister);
unit.station.v = this.f_register[tokens[0] as keyof FloatingPointRegister];
break;
case 'fsub':
this.fsub(tokens[0] as keyof FloatingPointRegister,
case RV64D.FMUL:
this.fmul(tokens[0] as keyof FloatingPointRegister,
tokens[1] as keyof FloatingPointRegister,
tokens[2] as keyof FloatingPointRegister);
unit.station.v = this.f_register[tokens[0] as keyof FloatingPointRegister];
break;
case 'fadd':
this.fadd(tokens[0] as keyof FloatingPointRegister,
case RV64D.FDIV:
this.fdiv(tokens[0] as keyof FloatingPointRegister,
tokens[1] as keyof FloatingPointRegister,
tokens[2] as keyof FloatingPointRegister);
unit.station.v = this.f_register[tokens[0] as keyof FloatingPointRegister];
Expand Down
20 changes: 20 additions & 0 deletions src/utils/rsic-v/isa.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

export enum RV64I {
// Base Integer Instruction Set
ADD = 'add',
ADDI = 'addi',
SUB = 'sub',

JAL = 'jal',
}

export enum RV64D {
// Standard Extension for Floating-Point
FLD = 'fld',
FSD = 'fsd',

FADD = 'fadd',
FSUB = 'fsub',
FMUL = 'fmul',
FDIV = 'fdiv',
}
Loading

1 comment on commit bdb068f

@vercel
Copy link

@vercel vercel bot commented on bdb068f Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.