Skip to content

Commit b066371

Browse files
authored
Merge pull request #4 from howjmay/basic
refactor: Refactor architecture
2 parents c340474 + 4ad2bc4 commit b066371

File tree

5 files changed

+128
-111
lines changed

5 files changed

+128
-111
lines changed

src/cpu.rs

+33-32
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::registers;
88
pub struct CPU {
99
// integer registers
1010
pub xregs: registers::XREGS,
11-
pub pc: u64,
11+
pub pc: u32,
1212

1313
pub bus: memory::BUS,
1414
}
@@ -114,22 +114,23 @@ impl CPU {
114114
// RV32I
115115
// see page 64 at https://riscv.org/wp-content/uploads/2016/06/riscv-spec-v2.1.pdf
116116
pub fn exec_lui(cpu: &mut CPU, instr: u32) {
117-
let imm = (imm_U(instr) as i32) as u64;
117+
let imm = (imm_u(instr) as i32) as u32;
118118
cpu.xregs.regs[rd(instr) as usize] = imm;
119119
}
120120
pub fn exec_auipc(cpu: &mut CPU, instr: u32) {
121-
let imm = (imm_U(instr) as i32) as i64;
122-
cpu.xregs.regs[rd(instr) as usize] = (cpu.pc as i64 + imm) as u64;
121+
let imm = imm_u(instr) as i32;
122+
cpu.xregs.regs[rd(instr) as usize] = (cpu.pc as i32).wrapping_add(imm) as u32;
123123
}
124124
pub fn exec_jal(cpu: &mut CPU, instr: u32) {
125-
let imm = (imm_J(instr) as i32) as i64;
125+
let imm = imm_j(instr) as i32;
126126
cpu.xregs.regs[rd(instr) as usize] = cpu.pc + 4;
127-
cpu.pc = (cpu.pc as i64 + imm) as u64;
127+
cpu.pc = (cpu.pc as i32 + imm) as u32;
128128
}
129129
pub fn exec_jalr(cpu: &mut CPU, instr: u32) {
130-
let imm = (imm_J(instr) as i32) as i64;
130+
let imm = imm_i(instr) as i32;
131131
cpu.xregs.regs[rd(instr) as usize] = cpu.pc + 4;
132-
cpu.pc = (cpu.pc as i64 + imm) as u64;
132+
// ignore the last 1 bit with 0xfffffffe
133+
cpu.pc = (cpu.xregs.regs[rs1(instr) as usize] as i32).wrapping_add(imm) as u32 & 0xfffffffe;
133134
}
134135
pub fn exec_beq(cpu: &mut CPU, instr: u32) {}
135136
pub fn exec_bne(cpu: &mut CPU, instr: u32) {}
@@ -149,51 +150,51 @@ pub fn exec_sh(cpu: &mut CPU, instr: u32) {}
149150
pub fn exec_sw(cpu: &mut CPU, instr: u32) {}
150151
pub fn exec_sd(cpu: &mut CPU, instr: u32) {}
151152
pub fn exec_addi(cpu: &mut CPU, instr: u32) {
152-
let imm = imm_I(instr);
153-
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] + imm as u64;
153+
let imm = imm_i(instr);
154+
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] + imm as u32;
154155
}
155156
pub fn exec_slti(cpu: &mut CPU, instr: u32) {
156-
let imm = imm_I(instr);
157+
let imm = imm_i(instr);
157158
cpu.xregs.regs[rd(instr) as usize] =
158-
((cpu.xregs.regs[rs1(instr) as usize] as i64) < (imm as i64)) as u64;
159+
((cpu.xregs.regs[rs1(instr) as usize] as i32) < (imm as i32)) as u32;
159160
}
160161
pub fn exec_sltiu(cpu: &mut CPU, instr: u32) {
161-
let imm = imm_I(instr);
162-
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] < imm as u64) as u64;
162+
let imm = imm_i(instr);
163+
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] < imm as u32) as u32;
163164
}
164165
pub fn exec_xori(cpu: &mut CPU, instr: u32) {
165-
let imm = imm_I(instr);
166-
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] ^ imm as u64;
166+
let imm = imm_i(instr);
167+
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] ^ imm as u32;
167168
}
168169
pub fn exec_ori(cpu: &mut CPU, instr: u32) {
169-
let imm = imm_I(instr);
170-
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] | imm as u64;
170+
let imm = imm_i(instr);
171+
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] | imm as u32;
171172
}
172173
pub fn exec_andi(cpu: &mut CPU, instr: u32) {
173-
let imm = imm_I(instr);
174-
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] & imm as u64;
174+
let imm = imm_i(instr);
175+
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] & imm as u32;
175176
}
176177
pub fn exec_slli(cpu: &mut CPU, instr: u32) {
177-
let imm = imm_I(instr);
178-
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] << imm as u64;
178+
let imm = imm_i(instr);
179+
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] << imm as u32;
179180
}
180181
pub fn exec_srli(cpu: &mut CPU, instr: u32) {
181-
let imm = imm_I(instr);
182-
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] >> imm as u64;
182+
let imm = imm_i(instr);
183+
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] >> imm as u32;
183184
}
184185
pub fn exec_srai(cpu: &mut CPU, instr: u32) {
185-
let imm = imm_I(instr);
186-
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] as i64 >> imm) as u64;
186+
let imm = imm_i(instr);
187+
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] as i32 >> imm) as u32;
187188
}
188189
pub fn exec_add(cpu: &mut CPU, instr: u32) {
189-
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] as i64
190-
+ cpu.xregs.regs[rs2(instr) as usize] as i64)
191-
as u64;
190+
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] as i32
191+
+ cpu.xregs.regs[rs2(instr) as usize] as i32)
192+
as u32;
192193
}
193194
pub fn exec_sub(cpu: &mut CPU, instr: u32) {
194-
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] as i64
195-
- cpu.xregs.regs[rs2(instr) as usize] as i64)
196-
as u64;
195+
cpu.xregs.regs[rd(instr) as usize] = (cpu.xregs.regs[rs1(instr) as usize] as i32
196+
- cpu.xregs.regs[rs2(instr) as usize] as i32)
197+
as u32;
197198
}
198199
pub fn exec_sll(cpu: &mut CPU, instr: u32) {}
199200
pub fn exec_slt(cpu: &mut CPU, instr: u32) {}

src/memory.rs

+48-48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// pub mod memory;
22

3-
pub const MEM_BASE: u64 = 0x80000000; // defined in QEMU
4-
pub const MEM_SIZE: u64 = 1024;
3+
pub const MEM_BASE: u32 = 0x80000000; // defined in QEMU
4+
pub const MEM_SIZE: u32 = 1024;
55

66
#[derive(Debug)]
77
pub struct BUS {
@@ -12,10 +12,10 @@ impl BUS {
1212
pub fn new() -> Self {
1313
BUS { mem: MEMORY::new() }
1414
}
15-
pub fn load(self, addr: u64, size: u64) -> u32 {
15+
pub fn load(self, addr: u32, size: u32) -> u32 {
1616
return self.mem.load(addr, size) as u32;
1717
}
18-
pub fn store(&mut self, addr: u64, size: u64, value: u64) {
18+
pub fn store(&mut self, addr: u32, size: u32, value: u32) {
1919
self.mem.store(addr, size, value);
2020
}
2121
}
@@ -32,78 +32,78 @@ impl MEMORY {
3232
}
3333
}
3434

35-
fn load(self, addr: u64, size: u64) -> u64 {
35+
fn load(self, addr: u32, size: u32) -> u32 {
3636
match size {
3737
8 => return self.load8(addr),
3838
16 => return self.load16(addr),
3939
32 => return self.load32(addr),
40-
64 => return self.load64(addr),
40+
// 64 => return self.load64(addr),
4141
_ => panic!("wrong load size"),
4242
}
4343
}
44-
fn store(&mut self, addr: u64, size: u64, value: u64) {
44+
fn store(&mut self, addr: u32, size: u32, value: u32) {
4545
match size {
4646
8 => self.store8(addr, value),
4747
16 => self.store16(addr, value),
4848
32 => self.store32(addr, value),
49-
64 => self.store64(addr, value),
49+
// 64 => self.store64(addr, value),
5050
_ => panic!("wrong store size"),
5151
}
5252
}
5353

5454
// load funcs
55-
fn load8(self, addr: u64) -> u64 {
55+
fn load8(self, addr: u32) -> u32 {
5656
let index = (addr - MEM_BASE) as usize;
57-
return self.mem[index] as u64;
57+
return self.mem[index] as u32;
5858
}
59-
fn load16(self, addr: u64) -> u64 {
59+
fn load16(self, addr: u32) -> u32 {
6060
let index = (addr - MEM_BASE) as usize;
61-
return self.mem[index] as u64 | ((self.mem[index + 1] as u64) << 8);
61+
return self.mem[index] as u32 | ((self.mem[index + 1] as u32) << 8);
6262
}
63-
fn load32(self, addr: u64) -> u64 {
63+
fn load32(self, addr: u32) -> u32 {
6464
let index = (addr - MEM_BASE) as usize;
65-
return self.mem[index] as u64
66-
| ((self.mem[index + 1] as u64) << 8)
67-
| ((self.mem[index + 2] as u64) << 16)
68-
| ((self.mem[index + 3] as u64) << 24);
69-
}
70-
fn load64(self, addr: u64) -> u64 {
71-
let index = (addr - MEM_BASE) as usize;
72-
return self.mem[index] as u64
73-
| ((self.mem[index + 1] as u64) << 8)
74-
| ((self.mem[index + 2] as u64) << 16)
75-
| ((self.mem[index + 3] as u64) << 24)
76-
| ((self.mem[index + 4] as u64) << 32)
77-
| ((self.mem[index + 5] as u64) << 40)
78-
| ((self.mem[index + 6] as u64) << 48)
79-
| ((self.mem[index + 7] as u64) << 56);
65+
return self.mem[index] as u32
66+
| ((self.mem[index + 1] as u32) << 8)
67+
| ((self.mem[index + 2] as u32) << 16)
68+
| ((self.mem[index + 3] as u32) << 24);
8069
}
70+
// fn load64(self, addr: u32) -> u32 {
71+
// let index = (addr - MEM_BASE) as usize;
72+
// return self.mem[index] as u32
73+
// | ((self.mem[index + 1] as u32) << 8)
74+
// | ((self.mem[index + 2] as u32) << 16)
75+
// | ((self.mem[index + 3] as u32) << 24)
76+
// | ((self.mem[index + 4] as u32) << 32)
77+
// | ((self.mem[index + 5] as u32) << 40)
78+
// | ((self.mem[index + 6] as u32) << 48)
79+
// | ((self.mem[index + 7] as u32) << 56);
80+
// }
8181

8282
// store funcs
83-
fn store8(&mut self, addr: u64, value: u64) {
84-
let index = (addr - MEM_BASE) as usize;
85-
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
86-
}
87-
fn store16(&mut self, addr: u64, value: u64) {
83+
fn store8(&mut self, addr: u32, value: u32) {
8884
let index = (addr - MEM_BASE) as usize;
89-
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
90-
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u64)) as u8;
85+
self.mem[index] = (value & (std::u8::MAX as u32)) as u8;
9186
}
92-
fn store32(&mut self, addr: u64, value: u64) {
87+
fn store16(&mut self, addr: u32, value: u32) {
9388
let index = (addr - MEM_BASE) as usize;
94-
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
95-
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u64)) as u8;
96-
self.mem[index + 2] = ((value >> 16) & (std::u8::MAX as u64)) as u8;
89+
self.mem[index] = (value & (std::u8::MAX as u32)) as u8;
90+
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u32)) as u8;
9791
}
98-
fn store64(&mut self, addr: u64, value: u64) {
92+
fn store32(&mut self, addr: u32, value: u32) {
9993
let index = (addr - MEM_BASE) as usize;
100-
self.mem[index] = (value & (std::u8::MAX as u64)) as u8;
101-
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u64)) as u8;
102-
self.mem[index + 2] = ((value >> 16) & (std::u8::MAX as u64)) as u8;
103-
self.mem[index + 3] = ((value >> 24) & (std::u8::MAX as u64)) as u8;
104-
self.mem[index + 4] = ((value >> 32) & (std::u8::MAX as u64)) as u8;
105-
self.mem[index + 5] = ((value >> 40) & (std::u8::MAX as u64)) as u8;
106-
self.mem[index + 6] = ((value >> 48) & (std::u8::MAX as u64)) as u8;
107-
self.mem[index + 7] = ((value >> 56) & (std::u8::MAX as u64)) as u8;
94+
self.mem[index] = (value & (std::u8::MAX as u32)) as u8;
95+
self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u32)) as u8;
96+
self.mem[index + 2] = ((value >> 16) & (std::u8::MAX as u32)) as u8;
10897
}
98+
// fn store64(&mut self, addr: u32, value: u32) {
99+
// let index = (addr - MEM_BASE) as usize;
100+
// self.mem[index] = (value & (std::u8::MAX as u32)) as u8;
101+
// self.mem[index + 1] = ((value >> 8) & (std::u8::MAX as u32)) as u8;
102+
// self.mem[index + 2] = ((value >> 16) & (std::u8::MAX as u32)) as u8;
103+
// self.mem[index + 3] = ((value >> 24) & (std::u8::MAX as u32)) as u8;
104+
// self.mem[index + 4] = ((value >> 32) & (std::u8::MAX as u32)) as u8;
105+
// self.mem[index + 5] = ((value >> 40) & (std::u8::MAX as u32)) as u8;
106+
// self.mem[index + 6] = ((value >> 48) & (std::u8::MAX as u32)) as u8;
107+
// self.mem[index + 7] = ((value >> 56) & (std::u8::MAX as u32)) as u8;
108+
// }
109109
}

src/opcode.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -100,41 +100,41 @@ pub fn rs2(instr: u32) -> u32 {
100100

101101
pub fn shamt(instr: u32) -> u32 {
102102
// shamt[4:5] = imm[5:0]
103-
return (imm_I(instr) & 0x1f) as u32;
103+
return (imm_i(instr) & 0x1f) as u32;
104104
}
105105

106-
pub fn csr(instr: u32) -> u64 {
106+
pub fn csr(instr: u32) -> u32 {
107107
// csr[11:0] = inst[31:20]
108-
return ((instr & 0xfff00000) >> 20) as u64;
108+
return ((instr & 0xfff00000) >> 20) as u32;
109109
}
110110

111-
pub fn imm_B(instr: u32) -> u64 {
111+
pub fn imm_b(instr: u32) -> u32 {
112112
// imm[12|10:5|4:1|11] = inst[31|30:25|11:8|7]
113-
return ((instr & 0x80000000) >> 19) as u64
114-
| ((instr & 0x80) << 4) as u64 // imm[11]
115-
| ((instr >> 20) & 0x7e0) as u64 // imm[10:5]
116-
| ((instr >> 7) & 0x1e) as u64; // imm[4:1]
113+
return ((instr & 0x80000000) >> 19) as u32
114+
| ((instr & 0x80) << 4) as u32 // imm[11]
115+
| ((instr >> 20) & 0x7e0) as u32 // imm[10:5]
116+
| ((instr >> 7) & 0x1e) as u32; // imm[4:1]
117117
}
118118

119-
pub fn imm_S(instr: u32) -> u64 {
119+
pub fn imm_s(instr: u32) -> u32 {
120120
// imm[11:5] = inst[31:25], imm[4:0] = inst[11:7]
121-
return ((instr & 0xfe000000) >> 20) as u64 | ((instr >> 7) & 0x1f) as u64;
121+
return ((instr & 0xfe000000) >> 20) as u32 | ((instr >> 7) & 0x1f) as u32;
122122
}
123123

124-
pub fn imm_I(instr: u32) -> i32 {
124+
pub fn imm_i(instr: u32) -> i32 {
125125
// imm[11:0] = inst[31:20]
126126
return (instr & 0xfff00000) as i32 >> 20;
127127
}
128128

129-
pub fn imm_U(instr: u32) -> u64 {
129+
pub fn imm_u(instr: u32) -> u32 {
130130
// imm[31:12] = inst[31:12]
131-
return (instr & 0xfffff000) as u64;
131+
return (instr & 0xfffff000) as u32;
132132
}
133133

134-
pub fn imm_J(instr: u32) -> u64 {
134+
pub fn imm_j(instr: u32) -> u32 {
135135
// imm[20|10:1|11|19:12] = inst[31|30:21|20|19:12]
136-
return (((instr & 0x80000000) as i32 as i64 >> 11) as u64)// imm[20]
137-
| ((instr & 0x3ff00000) >> 20) as u64 // imm[10:1]
138-
| ((instr & 0x80000) >> 9) as u64 // imm[11]
139-
| (instr & 0xff000) as u64; // imm[19:12]
136+
return (((instr & 0x80000000) as i32 >> 11) as u32)// imm[20]
137+
| ((instr & 0x3ff00000) >> 20) as u32 // imm[10:1]
138+
| ((instr & 0x80000) >> 9) as u32 // imm[11]
139+
| (instr & 0xff000) as u32; // imm[19:12]
140140
}

src/registers.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use core::fmt;
44

55
pub struct XREGS {
6-
pub regs: [u64; 32],
6+
pub regs: [u32; 32],
77
}
88

99
impl XREGS {
@@ -29,7 +29,7 @@ mod tests {
2929
fn xregs_debug() {
3030
let mut xregs = XREGS::new();
3131
for i in 0..32 {
32-
xregs.regs[i] = (i * 11) as u64;
32+
xregs.regs[i] = (i * 11) as u32;
3333
}
3434
println!("{xregs:#?}")
3535
}

0 commit comments

Comments
 (0)