Skip to content

Commit c519353

Browse files
committed
2 parents 14e0fb9 + 9863f13 commit c519353

File tree

13 files changed

+367
-668
lines changed

13 files changed

+367
-668
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,7 @@ hs_err_pid*
346346
.bloop/
347347

348348
# Emitted Verilog
349-
generated/
349+
generated/
350+
351+
documentation/.obsidian/workspace.json
352+
documentation/.obsidian/appearance.json

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class MainTemplateSpec extends AnyFreeSpec with Matchers with ChiselSim {
9797
simulate(new Main()) { dut =>
9898
// 1. Initialize registers (example: write value to x1)
9999
dut.io.write_enable.poke(true.B)
100-
dut.io.write_addr.poke(1.U)
100+
dut.io.write_address.poke(1.U)
101101
dut.io.in.poke(42.U)
102102
dut.clock.step(1)
103103
dut.io.write_enable.poke(false.B)
@@ -111,8 +111,8 @@ class MainTemplateSpec extends AnyFreeSpec with Matchers with ChiselSim {
111111
112112
// 4. Read back a register value to verify the result
113113
// Always use the C port of the register file for reading.
114-
dut.io.read_addr_C.poke(1.U) // Which register to read
115-
dut.io.out_C.expect(42.U) // Expected result (example)
114+
dut.io.read_address_c.poke(1.U) // Which register to read
115+
dut.io.out_c.expect(42.U) // Expected result (example)
116116
}
117117
}
118118
}
Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,79 +12,79 @@ class RegistersSpec extends AnyFreeSpec with Matchers with ChiselSim {
1212
simulate(new Registers()) { dut =>
1313
// Write to x1
1414
dut.io.write_enable.poke(true.B)
15-
dut.io.write_addr.poke(1.U)
15+
dut.io.write_address.poke(1.U)
1616
dut.io.in.poke(123.U(32.W))
1717
dut.clock.step(1)
1818

1919
// Write to x2
20-
dut.io.write_addr.poke(2.U)
20+
dut.io.write_address.poke(2.U)
2121
dut.io.in.poke(456.U(32.W))
2222
dut.clock.step(1)
2323

2424
// Read both registers
25-
dut.io.read_addr_A.poke(1.U)
26-
dut.io.read_addr_B.poke(2.U)
27-
dut.io.out_A.expect(123.U(32.W))
28-
dut.io.out_B.expect(456.U(32.W))
25+
dut.io.read_address_a.poke(1.U)
26+
dut.io.read_address_b.poke(2.U)
27+
dut.io.out_a.expect(123.U(32.W))
28+
dut.io.out_b.expect(456.U(32.W))
2929
}
3030
}
3131

3232
"register x0 should always read as 0 and ignore writes" in {
3333
simulate(new Registers()) { dut =>
3434
// Attempt to write to x0
3535
dut.io.write_enable.poke(true.B)
36-
dut.io.write_addr.poke(0.U)
36+
dut.io.write_address.poke(0.U)
3737
dut.io.in.poke(999.U(32.W))
3838
dut.clock.step(1)
3939

4040
// Read back x0
41-
dut.io.read_addr_A.poke(0.U)
42-
dut.io.read_addr_B.poke(0.U)
43-
dut.io.out_A.expect(0.U(32.W))
44-
dut.io.out_B.expect(0.U(32.W))
41+
dut.io.read_address_a.poke(0.U)
42+
dut.io.read_address_b.poke(0.U)
43+
dut.io.out_a.expect(0.U(32.W))
44+
dut.io.out_b.expect(0.U(32.W))
4545
}
4646
}
4747

4848
"registers should update only when write_enable is true" in {
4949
simulate(new Registers()) { dut =>
5050
// Disable writing
5151
dut.io.write_enable.poke(false.B)
52-
dut.io.write_addr.poke(3.U)
52+
dut.io.write_address.poke(3.U)
5353
dut.io.in.poke(111.U(32.W))
5454
dut.clock.step(1)
5555

5656
// Read back should still be 0
57-
dut.io.read_addr_A.poke(3.U)
58-
dut.io.out_A.expect(0.U(32.W))
57+
dut.io.read_address_a.poke(3.U)
58+
dut.io.out_a.expect(0.U(32.W))
5959
}
6060
}
6161

6262
"registers should correctly handle multiple writes and reads" in {
6363
simulate(new Registers()) { dut =>
6464
// Write multiple registers
6565
dut.io.write_enable.poke(true.B)
66-
dut.io.write_addr.poke(4.U)
66+
dut.io.write_address.poke(4.U)
6767
dut.io.in.poke(10.U(32.W))
6868
dut.clock.step(1)
6969

70-
dut.io.write_addr.poke(5.U)
70+
dut.io.write_address.poke(5.U)
7171
dut.io.in.poke(20.U(32.W))
7272
dut.clock.step(1)
7373

74-
dut.io.write_addr.poke(6.U)
74+
dut.io.write_address.poke(6.U)
7575
dut.io.in.poke(30.U(32.W))
7676
dut.clock.step(1)
7777

7878
// Read them back
79-
dut.io.read_addr_A.poke(4.U)
80-
dut.io.read_addr_B.poke(5.U)
81-
dut.io.out_A.expect(10.U(32.W))
82-
dut.io.out_B.expect(20.U(32.W))
79+
dut.io.read_address_a.poke(4.U)
80+
dut.io.read_address_b.poke(5.U)
81+
dut.io.out_a.expect(10.U(32.W))
82+
dut.io.out_b.expect(20.U(32.W))
8383

84-
dut.io.read_addr_A.poke(6.U)
85-
dut.io.read_addr_B.poke(4.U)
86-
dut.io.out_A.expect(30.U(32.W))
87-
dut.io.out_B.expect(10.U(32.W))
84+
dut.io.read_address_a.poke(6.U)
85+
dut.io.read_address_b.poke(4.U)
86+
dut.io.out_a.expect(30.U(32.W))
87+
dut.io.out_b.expect(10.U(32.W))
8888
}
8989
}
9090
}

documentation/.obsidian/workspace.json

Lines changed: 0 additions & 182 deletions
This file was deleted.

documentation/Modules/Hart.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
## Overview
2+
The Hart is the "hardware execution unit". This is the complex stuff comes together to actually execute the instructions. Right now it's stored in the `main.scala` file but we'll probably want to move it over to `hart.scala` later.
3+
## Instruction Staging
4+
Right now for simplicity, we're not doing anything too complex with how we're loading instructions. The way it works currently is a simple stage counter.
5+
### Stage 0
6+
The instruction at the program pointer is requested from memory.
7+
### Stage 1
8+
The instruction is available from memory and the decoder is now emitting the decoded instruction. We store the decoded instructions in buffers for access in later stages. Most instructions can simply execute in this stage and then set the stage counter back to 0 and increase the program pointer.
9+
## Stage 2
10+
Currently only the `LW` instruction uses stage 2, since in stage 1 `LW` requests the info from memory and then in stage 2 it takes the value from memory and writes it to the register.
11+
## Implemented Instructions
12+
### Main Integer Instructions
13+
- [x] LUI
14+
- [x] AUIPC
15+
- [x] ADDI
16+
- [x] SLTI
17+
- [x] SLTIU
18+
- [x] XORI
19+
- [x] ORI
20+
- [x] ANDI
21+
- [ ] SLLI
22+
- [ ] SRLI
23+
- [ ] SRAI
24+
- [x] ADD
25+
- [x] SUB
26+
- [ ] SLL
27+
- [ ] SLT
28+
- [ ] SLTU
29+
- [ ] XOR
30+
- [ ] SRL
31+
- [ ] SRA
32+
- [ ] OR
33+
- [ ] AND
34+
- [ ] LB
35+
- [ ] LH
36+
- [x] LW
37+
- [ ] LBU
38+
- [ ] LHU
39+
- [ ] SB
40+
- [ ] SH
41+
- [x] SW
42+
- [ ] JAL
43+
- [ ] JALR
44+
- [ ] BEQ
45+
- [ ] BNE
46+
- [ ] BLT
47+
- [ ] BGE
48+
- [ ] BLTU
49+
- [ ] BGEU
50+
### Other Integer Instructions
51+
- [ ] FENCE
52+
- [ ] FENCEI
53+
- [ ] ECALL
54+
- [ ] EBREAK
55+
- [ ] SRET
56+
- [ ] MRET
57+
- [ ] WFI
58+
- [ ] SFENCEVMA
59+
- [ ] CSRRW
60+
- [ ] CSRRS
61+
- [ ] CSRRC
62+
- [ ] CSRRWI
63+
- [ ] CSRRSI
64+
- [ ] CSRRCI

documentation/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Welcome to the documentation for our RISC-V procesor!
22
## Modules
33
- [[Decoder]]
4+
- [[Hart]]

0 commit comments

Comments
 (0)