aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-12 21:27:41 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-12 21:27:41 +0200
commitdeb7d0a6fc76d5250c238d479cf97d4755abef01 (patch)
tree395c266ff4757e83e151d1286d6d2388e63d9a9c
parent008059fbe4e960a10bb4c444013129e0aaa02818 (diff)
downloadriscv_cpu-deb7d0a6fc76d5250c238d479cf97d4755abef01.tar.gz
riscv_cpu-deb7d0a6fc76d5250c238d479cf97d4755abef01.zip
refactoring
-rw-r--r--debug/cpu.gtkw229
-rw-r--r--gentestvec/gentestvec_register_file.c3
-rw-r--r--prog/src/prog.s58
-rw-r--r--sim/testbench_cpu.v4
-rw-r--r--sim/testbench_register_file.v14
-rw-r--r--src/alu_a_src_mux.v16
-rw-r--r--src/alu_b_src_mux.v16
-rw-r--r--src/alu_op_decode.v12
-rw-r--r--src/alu_result_reg.v12
-rw-r--r--src/control_unit.v222
-rw-r--r--src/cpu.v255
-rw-r--r--src/data_reg.v13
-rw-r--r--src/immediate_extend.v20
-rw-r--r--src/instruction_reg.v17
-rw-r--r--src/led_unit.v18
-rw-r--r--src/mem_addr_src_mux.v15
-rw-r--r--src/memory_interface.v (renamed from src/memory_unit.v)31
-rw-r--r--src/pc_reg.v18
-rw-r--r--src/ram.v13
-rw-r--r--src/register_file.v94
-rw-r--r--src/register_file_reg.v17
-rw-r--r--src/result_mux.v16
-rw-r--r--src/top.v34
23 files changed, 650 insertions, 497 deletions
diff --git a/debug/cpu.gtkw b/debug/cpu.gtkw
index 810c8f5..e611f38 100644
--- a/debug/cpu.gtkw
+++ b/debug/cpu.gtkw
@@ -1,230 +1,159 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
-[*] Wed May 8 10:49:57 2024
+[*] Sun May 12 19:27:12 2024
[*]
[dumpfile] "/Users/flavian/Documents/hobbies/electronics/projects/riscv_cpu/build/waveform_cpu.vcd"
-[dumpfile_mtime] "Wed May 8 10:49:11 2024"
-[dumpfile_size] 39809
+[dumpfile_mtime] "Sun May 12 19:21:04 2024"
+[dumpfile_size] 75506
[savefile] "/Users/flavian/Documents/hobbies/electronics/projects/riscv_cpu/debug/cpu.gtkw"
-[timestart] 0
+[timestart] 277300
[size] 1512 916
-[pos] -1 -1
-*-16.000000 29400 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[pos] -1 0
+*-15.000000 27100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] testbench_register_file.
-[treeopen] testbench_register_file.uut.
-[treeopen] testbench_register_file.uut.alu.
-[treeopen] testbench_register_file.uut.cu.
-[treeopen] testbench_register_file.uut.mu.
-[treeopen] testbench_register_file.uut.mu.ram.
-[treeopen] testbench_register_file.uut.mu.rom.
+[treeopen] testbench_register_file.cpu.
[sst_width] 253
-[signals_width] 252
+[signals_width] 390
[sst_expanded] 1
[sst_vpaned_height] 278
@28
testbench_register_file.clk
testbench_register_file.rst
-@23
+@24
testbench_register_file.clk_cycle_count[31:0]
@200
-
@22
[color] 2
-testbench_register_file.uut.cu.state[3:0]
-[color] 2
-testbench_register_file.uut.cu.next_state[3:0]
-@200
--
+testbench_register_file.cpu.control_unit.state[3:0]
@28
-testbench_register_file.uut.cu.instr_we
+testbench_register_file.cpu.instr_we
@22
-testbench_register_file.uut.pc[31:0]
-@c00022
-testbench_register_file.uut.pc_buf[31:0]
-@28
-(0)testbench_register_file.uut.pc_buf[31:0]
-(1)testbench_register_file.uut.pc_buf[31:0]
-(2)testbench_register_file.uut.pc_buf[31:0]
-(3)testbench_register_file.uut.pc_buf[31:0]
-(4)testbench_register_file.uut.pc_buf[31:0]
-(5)testbench_register_file.uut.pc_buf[31:0]
-(6)testbench_register_file.uut.pc_buf[31:0]
-(7)testbench_register_file.uut.pc_buf[31:0]
-(8)testbench_register_file.uut.pc_buf[31:0]
-(9)testbench_register_file.uut.pc_buf[31:0]
-(10)testbench_register_file.uut.pc_buf[31:0]
-(11)testbench_register_file.uut.pc_buf[31:0]
-(12)testbench_register_file.uut.pc_buf[31:0]
-(13)testbench_register_file.uut.pc_buf[31:0]
-(14)testbench_register_file.uut.pc_buf[31:0]
-(15)testbench_register_file.uut.pc_buf[31:0]
-(16)testbench_register_file.uut.pc_buf[31:0]
-(17)testbench_register_file.uut.pc_buf[31:0]
-(18)testbench_register_file.uut.pc_buf[31:0]
-(19)testbench_register_file.uut.pc_buf[31:0]
-(20)testbench_register_file.uut.pc_buf[31:0]
-(21)testbench_register_file.uut.pc_buf[31:0]
-(22)testbench_register_file.uut.pc_buf[31:0]
-(23)testbench_register_file.uut.pc_buf[31:0]
-(24)testbench_register_file.uut.pc_buf[31:0]
-(25)testbench_register_file.uut.pc_buf[31:0]
-(26)testbench_register_file.uut.pc_buf[31:0]
-(27)testbench_register_file.uut.pc_buf[31:0]
-(28)testbench_register_file.uut.pc_buf[31:0]
-(29)testbench_register_file.uut.pc_buf[31:0]
-(30)testbench_register_file.uut.pc_buf[31:0]
-(31)testbench_register_file.uut.pc_buf[31:0]
-@1401200
--group_end
+testbench_register_file.cpu.instr[31:0]
@200
-
@22
-testbench_register_file.uut.instruction[31:0]
-testbench_register_file.uut.opcode[6:0]
-@28
-testbench_register_file.uut.funct3[2:0]
-@22
-testbench_register_file.uut.funct7[6:0]
+testbench_register_file.cpu.imm[31:0]
@200
-
@22
-testbench_register_file.uut.immediate[31:0]
-@200
--
-@28
-[color] 6
-testbench_register_file.uut.cu.mem_addr_src
-@22
-[color] 6
-testbench_register_file.uut.mu.addr[31:0]
-[color] 6
-testbench_register_file.uut.mu.read_data[31:0]
+testbench_register_file.cpu.pc[31:0]
+testbench_register_file.cpu.pc_buf[31:0]
@28
-[color] 6
-testbench_register_file.uut.mu.we
-@22
-[color] 6
-testbench_register_file.uut.mu.write_data[31:0]
-@200
--
-@28
-[color] 2
-testbench_register_file.uut.alu_a_src[1:0]
-[color] 2
-testbench_register_file.uut.alu_b_src[1:0]
+testbench_register_file.cpu.pc_we
@200
-
+@22
+testbench_register_file.cpu.mem_addr[31:0]
+testbench_register_file.cpu.mem_rd[31:0]
+@23
+testbench_register_file.cpu.rd2_buf[31:0]
@28
-[color] 2
-testbench_register_file.uut.cu.alu_ctrl[1:0]
+testbench_register_file.cpu.mem_we
@22
-[color] 2
-testbench_register_file.uut.alu_op[3:0]
+testbench_register_file.cpu.data_buf[31:0]
@200
-
@22
-[color] 2
-testbench_register_file.uut.a[31:0]
-[color] 2
-testbench_register_file.uut.a_buf[31:0]
-[color] 2
-testbench_register_file.uut.b[31:0]
-[color] 2
-testbench_register_file.uut.b_buf[31:0]
-@200
--
+[color] 5
+testbench_register_file.cpu.alu_a[31:0]
+[color] 5
+testbench_register_file.cpu.alu_b[31:0]
+@28
+[color] 5
+testbench_register_file.cpu.alu_a_src[1:0]
+[color] 5
+testbench_register_file.cpu.alu_b_src[1:0]
@22
-[color] 2
-testbench_register_file.uut.alu_result[31:0]
+[color] 5
+testbench_register_file.cpu.alu_op[3:0]
@28
-[color] 2
-testbench_register_file.uut.alu_zero
-[color] 2
-testbench_register_file.uut.alu_equal
+testbench_register_file.cpu.alu_zero
+@22
+[color] 5
+testbench_register_file.cpu.alu_result[31:0]
@200
-
-@28
-testbench_register_file.uut.result_src[1:0]
@22
-testbench_register_file.uut.result[31:0]
+testbench_register_file.cpu.result[31:0]
@200
-
@22
[color] 3
-testbench_register_file.uut.rf.reg_x0_zero[31:0]
+testbench_register_file.cpu.register_file.ra1[4:0]
[color] 3
-testbench_register_file.uut.rf.reg_x1_ra[31:0]
+testbench_register_file.cpu.register_file.ra2[4:0]
[color] 3
-testbench_register_file.uut.rf.reg_x2_sp[31:0]
+testbench_register_file.cpu.register_file.wa3[4:0]
+@28
[color] 3
-testbench_register_file.uut.rf.reg_x3_gp[31:0]
+testbench_register_file.cpu.rf_we
+@200
+-
+@22
[color] 3
-testbench_register_file.uut.rf.reg_x4_tp[31:0]
+testbench_register_file.cpu.register_file.reg_x0_zero[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x5_t0[31:0]
+testbench_register_file.cpu.register_file.reg_x1_ra[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x6_t1[31:0]
+testbench_register_file.cpu.register_file.reg_x2_sp[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x7_t2[31:0]
+testbench_register_file.cpu.register_file.reg_x3_gp[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x8_s0_fp[31:0]
+testbench_register_file.cpu.register_file.reg_x4_tp[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x9_s1[31:0]
+testbench_register_file.cpu.register_file.reg_x5_t0[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x10_a0[31:0]
+testbench_register_file.cpu.register_file.reg_x6_t1[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x11_a1[31:0]
+testbench_register_file.cpu.register_file.reg_x7_t2[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x12_a2[31:0]
+testbench_register_file.cpu.register_file.reg_x8_s0_fp[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x13_a3[31:0]
+testbench_register_file.cpu.register_file.reg_x9_s1[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x14_a4[31:0]
+testbench_register_file.cpu.register_file.reg_x10_a0[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x15_a5[31:0]
+testbench_register_file.cpu.register_file.reg_x11_a1[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x16_a6[31:0]
+testbench_register_file.cpu.register_file.reg_x12_a2[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x17_a7[31:0]
+testbench_register_file.cpu.register_file.reg_x13_a3[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x18_s2[31:0]
+testbench_register_file.cpu.register_file.reg_x14_a4[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x19_s3[31:0]
+testbench_register_file.cpu.register_file.reg_x15_a5[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x20_s4[31:0]
+testbench_register_file.cpu.register_file.reg_x16_a6[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x21_s5[31:0]
+testbench_register_file.cpu.register_file.reg_x17_a7[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x22_s6[31:0]
+testbench_register_file.cpu.register_file.reg_x18_s2[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x23_s7[31:0]
+testbench_register_file.cpu.register_file.reg_x19_s3[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x24_s8[31:0]
+testbench_register_file.cpu.register_file.reg_x20_s4[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x25_s9[31:0]
+testbench_register_file.cpu.register_file.reg_x21_s5[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x26_s10[31:0]
+testbench_register_file.cpu.register_file.reg_x22_s6[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x27_s11[31:0]
+testbench_register_file.cpu.register_file.reg_x23_s7[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x28_t3[31:0]
+testbench_register_file.cpu.register_file.reg_x24_s8[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x29_t4[31:0]
+testbench_register_file.cpu.register_file.reg_x25_s9[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x30_t5[31:0]
+testbench_register_file.cpu.register_file.reg_x26_s10[31:0]
[color] 3
-testbench_register_file.uut.rf.reg_x31_t6[31:0]
-@200
--
-@22
+testbench_register_file.cpu.register_file.reg_x27_s11[31:0]
[color] 3
-testbench_register_file.uut.rs1[4:0]
+testbench_register_file.cpu.register_file.reg_x28_t3[31:0]
[color] 3
-testbench_register_file.uut.rs2[4:0]
+testbench_register_file.cpu.register_file.reg_x29_t4[31:0]
[color] 3
-testbench_register_file.uut.rd[4:0]
-@28
+testbench_register_file.cpu.register_file.reg_x30_t5[31:0]
[color] 3
-testbench_register_file.uut.rf_we
+testbench_register_file.cpu.register_file.reg_x31_t6[31:0]
[pattern_trace] 1
[pattern_trace] 0
diff --git a/gentestvec/gentestvec_register_file.c b/gentestvec/gentestvec_register_file.c
index a9ff1c5..5a50d9b 100644
--- a/gentestvec/gentestvec_register_file.c
+++ b/gentestvec/gentestvec_register_file.c
@@ -14,9 +14,10 @@ void write_reg(uint32_t addr, uint32_t data, bool we) {
void test(uint32_t addr_rs0, uint32_t addr_rs1, uint32_t addr_rd2,
uint32_t data_rd2, bool we) {
+
+ write_reg(addr_rd2, data_rd2, we);
uint32_t data_rs0 = read_reg(addr_rs0);
uint32_t data_rs1 = read_reg(addr_rs1);
- write_reg(addr_rd2, data_rd2, we);
printf("%08X_%08X__%08X_%08X__%08X_%08X_%01X\n", addr_rs0, data_rs0, addr_rs1,
data_rs1, addr_rd2, data_rd2, we);
}
diff --git a/prog/src/prog.s b/prog/src/prog.s
index 4187c8a..8f23632 100644
--- a/prog/src/prog.s
+++ b/prog/src/prog.s
@@ -3,66 +3,14 @@
_start:
- # testing alu
-/*
- addi t0, zero, 5
- addi t1, zero, 3
-
- #add t2, t0, t1
- #sub t2, t0, t1
-
- xor t2, t0, t1
- or t2, t0, t1
- and t2, t0, t1
-
- slt t2, t0, t1
- slt t2, t1, t0
-
- addi t0, zero, -1
-
- slt t2, t0, t1
- slt t2, t1, t0
-
- sltu t2, t0, t1
- sltu t2, t1, t0
-
- addi t0, zero, 1
-
- sll t2, t0, 31
- sra t2, t2, 31
- sll t2, t0, 31
- srl t2, t2, 31
-*/
-
-
-# jal target
-# addi t0, zero, 2
-#0010 0000
-
-# addi t0, zero, 0x0010
-# slli t0, t0, 16
-# ori t0, t0, 0x0000
-
-# addi t1, zero, 0xff
-# sw t1, 0(t0)
-# lw t2, 0(t0)
-
- addi t0, zero, 1
- addi t1, zero, 2
- bge t0, t1, branch_taken
- addi t2, zero, 1
+ addi t0, zero, 3
+ addi t1, zero, 5
+ add t2, t0, t1
halt_loop:
j halt_loop
-branch_taken:
- addi t2, zero, 2
- j halt_loop
-
-#target:
-# addi t0, zero, 1
-# jalr zero, ra, 0
.section .data
diff --git a/sim/testbench_cpu.v b/sim/testbench_cpu.v
index 2a2e185..d6c3975 100644
--- a/sim/testbench_cpu.v
+++ b/sim/testbench_cpu.v
@@ -5,9 +5,9 @@ module testbench_register_file();
reg clk;
reg rst;
-cpu uut (
+cpu cpu (
.clk(clk),
- .rst(rst)
+ .rstn(!rst)
);
integer file, r, eof;
diff --git a/sim/testbench_register_file.v b/sim/testbench_register_file.v
index b0e0860..c1ca542 100644
--- a/sim/testbench_register_file.v
+++ b/sim/testbench_register_file.v
@@ -12,14 +12,14 @@ wire [31:0] data_rs0, data_rs1;
register_file uut (
.clk(clk),
- .rst(rst),
+ .rstn(!rst),
.we(we),
- .rs1(addr_rs0),
- .rs2(addr_rs1),
- .rd(addr_rd2),
- .rs1_data(data_rs0),
- .rs2_data(data_rs1),
- .rd_data(data_rd2)
+ .ra1(addr_rs0),
+ .ra2(addr_rs1),
+ .wa3(addr_rd2),
+ .rd1(data_rs0),
+ .rd2(data_rs1),
+ .wd3(data_rd2)
);
integer file, r, eof;
diff --git a/src/alu_a_src_mux.v b/src/alu_a_src_mux.v
new file mode 100644
index 0000000..0518e0a
--- /dev/null
+++ b/src/alu_a_src_mux.v
@@ -0,0 +1,16 @@
+module alu_a_src_mux (
+ input [31:0] src_pc, src_pc_buf, src_rd1_buf,
+ input [1:0] alu_a_src,
+ output reg [31:0] alu_a
+);
+
+always @(*) begin
+ case (alu_a_src)
+ 2'b00: alu_a <= src_pc;
+ 2'b01: alu_a <= src_pc_buf;
+ 2'b10: alu_a <= src_rd1_buf;
+ default: alu_a <= 32'b0;
+ endcase
+end
+
+endmodule
diff --git a/src/alu_b_src_mux.v b/src/alu_b_src_mux.v
new file mode 100644
index 0000000..e7df223
--- /dev/null
+++ b/src/alu_b_src_mux.v
@@ -0,0 +1,16 @@
+module alu_b_src_mux (
+ input [31:0] src_rd2_buf, src_imm,
+ input [1:0] alu_b_src,
+ output reg [31:0] alu_b
+);
+
+always @(*) begin
+ case (alu_b_src)
+ 2'b00: alu_b <= src_rd2_buf;
+ 2'b01: alu_b <= src_imm;
+ 2'b10: alu_b <= 32'h4;
+ default: alu_b <= 32'b0;
+ endcase
+end
+
+endmodule
diff --git a/src/alu_op_decode.v b/src/alu_op_decode.v
index b9db664..5eefcd8 100644
--- a/src/alu_op_decode.v
+++ b/src/alu_op_decode.v
@@ -31,6 +31,7 @@ always @ (*) begin
3'b101: alu_op <= funct7[5] ? ALU_OP_SRA : ALU_OP_SRL;
3'b110: alu_op <= ALU_OP_OR;
3'b111: alu_op <= ALU_OP_AND;
+ default: alu_op <= ALU_OP_ADD;
endcase
end
7'b0010011: begin // ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI
@@ -43,29 +44,40 @@ always @ (*) begin
3'b101: alu_op <= funct7[5] ? ALU_OP_SRA : ALU_OP_SRL;
3'b110: alu_op <= ALU_OP_OR;
3'b111: alu_op <= ALU_OP_AND;
+ default: alu_op <= ALU_OP_ADD;
endcase
end
7'b0000011: begin // LB, LH, LW, LBU, LHU
+ alu_op <= ALU_OP_ADD;
end
7'b1100111: begin // JALR
+ alu_op <= ALU_OP_ADD;
end
7'b0100011: begin // SB, SH, SW
+ alu_op <= ALU_OP_ADD;
end
7'b1100011: begin // BEQ, BNE, BLT, BGE, BLTU, BGEU
if ((funct3 == 3'b000) | (funct3 == 3'b001)) alu_op <= ALU_OP_SUB;
else if ((funct3 == 3'b100) | (funct3 == 3'b101)) alu_op <= ALU_OP_SLT;
else if ((funct3 == 3'b110) | (funct3 == 3'b111)) alu_op <= ALU_OP_SLTU;
+ else alu_op <= ALU_OP_ADD;
end
7'b0110111: begin // LUI
+ alu_op <= ALU_OP_ADD;
end
7'b0010111: begin // AUIPC
+ alu_op <= ALU_OP_ADD;
end
7'b1101111: begin // JAL
+ alu_op <= ALU_OP_ADD;
end
7'b0001111: begin // FENCE, FENCE.I
+ alu_op <= ALU_OP_ADD;
end
7'b1110011: begin // ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI
+ alu_op <= ALU_OP_ADD;
end
+ default: alu_op <= ALU_OP_ADD;
endcase
end
diff --git a/src/alu_result_reg.v b/src/alu_result_reg.v
new file mode 100644
index 0000000..b915bdb
--- /dev/null
+++ b/src/alu_result_reg.v
@@ -0,0 +1,12 @@
+module alu_result_reg (
+ input clk, rstn,
+ input [31:0] alu_result_in,
+ output reg [31:0] alu_result_buf
+);
+
+always @ (posedge clk) begin
+ if (!rstn) alu_result_buf <= 32'b0;
+ else alu_result_buf <= alu_result_in;
+end
+
+endmodule
diff --git a/src/control_unit.v b/src/control_unit.v
index 09129bd..f6d99ec 100644
--- a/src/control_unit.v
+++ b/src/control_unit.v
@@ -1,9 +1,9 @@
module control_unit (
- input clk, rst,
- input [6:0] opcode,
- input [2:0] funct3,
- input [6:0] funct7,
+ input clk,
+ input rstn,
+ input [31:0] instr,
input alu_zero,
+ output reg [2:0] imm_src,
output pc_we,
output reg mem_addr_src,
output reg mem_we,
@@ -28,16 +28,51 @@ parameter s00_fetch = 4'h0,
s10_jalr = 4'ha,
s11_br = 4'hb;
+
+parameter INSTRUCTION_FORMAT_UNKNOWN = 3'b000,
+ INSTRUCTION_FORMAT_R = 3'b001,
+ INSTRUCTION_FORMAT_I = 3'b010,
+ INSTRUCTION_FORMAT_S = 3'b011,
+ INSTRUCTION_FORMAT_B = 3'b100,
+ INSTRUCTION_FORMAT_U = 3'b101,
+ INSTRUCTION_FORMAT_J = 3'b110;
+
+wire [6:0] opcode;
+wire [2:0] funct3;
+wire [6:0] funct7;
+
+assign opcode = instr[6:0];
+assign funct3 = instr[14:12];
+assign funct7 = instr[31:25];
+
+
+always @ (*) begin
+ case (opcode)
+ 7'b0110011: imm_src <= INSTRUCTION_FORMAT_R; // ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND
+ 7'b0010011: imm_src <= INSTRUCTION_FORMAT_I; // ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI
+ 7'b0000011: imm_src <= INSTRUCTION_FORMAT_I; // LB, LH, LW, LBU, LHU
+ 7'b1100111: imm_src <= INSTRUCTION_FORMAT_I; // JALR
+ 7'b0100011: imm_src <= INSTRUCTION_FORMAT_S; // SB, SH, SW
+ 7'b1100011: imm_src <= INSTRUCTION_FORMAT_B; // BEQ, BNE, BLT, BGE, BLTU, BGEU
+ 7'b0110111: imm_src <= INSTRUCTION_FORMAT_U; // LUI
+ 7'b0010111: imm_src <= INSTRUCTION_FORMAT_U; // AUIPC
+ 7'b1101111: imm_src <= INSTRUCTION_FORMAT_J; // JAL
+ 7'b0001111: imm_src <= INSTRUCTION_FORMAT_I; // FENCE, FENCE.I
+ 7'b1110011: imm_src <= INSTRUCTION_FORMAT_I; // ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI
+ default: imm_src <= INSTRUCTION_FORMAT_UNKNOWN;
+ endcase
+end
+
reg [3:0] state, next_state;
-always @ (posedge clk or posedge rst) begin
- if (rst) state <= s00_fetch;
+always @ (posedge clk) begin
+ if (!rstn) state <= s00_fetch;
else state <= next_state;
end
always @ (*) begin
case(state)
- s00_fetch: next_state <= s01_decode;
+ s00_fetch: next_state <= s01_decode;
s01_decode: case(opcode)
7'b0000011: next_state <= s02_mem_addr;
7'b0100011: next_state <= s02_mem_addr;
@@ -46,11 +81,12 @@ always @ (*) begin
7'b1101111: next_state <= s09_jal;
7'b1100111: next_state <= s10_jalr;
7'b1100011: next_state <= s11_br;
-
+ default: next_state <= s00_fetch;
endcase
s02_mem_addr: case(opcode)
7'b0000011: next_state <= s03_mem_read;
7'b0100011: next_state <= s05_mem_write;
+ default: next_state <= s00_fetch;
endcase
s03_mem_read: next_state <= s04_mem_wb;
s04_mem_wb: next_state <= s00_fetch;
@@ -60,7 +96,8 @@ always @ (*) begin
s08_execute_i: next_state <= s07_alu_wb;
s09_jal: next_state <= s07_alu_wb;
s10_jalr: next_state <= s07_alu_wb;
- s11_br: next_state <= s00_fetch;
+ s11_br: next_state <= s00_fetch;
+ default: next_state <= s00_fetch;
endcase
end
@@ -70,80 +107,163 @@ reg alu_ctrl;
assign pc_we = ((alu_zero ^ funct3[0] ^ funct3[2]) & branch) | pc_update;
-
always @ (*) begin
- branch = 1'b0;
- pc_update = 1'b0;
- mem_we = 1'b0;
- rf_we = 1'b0;
- instr_we = 1'b0;
case(state)
s00_fetch: begin
mem_addr_src <= 1'b0;
- instr_we = 1'b1;
alu_a_src <= 2'b00;
alu_b_src <= 2'b10;
alu_ctrl <= 1'b1;
result_src <= 2'b10;
- pc_update = 1'b1;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b1;
+ pc_update <= 1'b1;
+ branch <= 1'b0;
end
s01_decode: begin
- alu_a_src <= 2'b01;
- alu_b_src <= 2'b01;
- alu_ctrl <= 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b01;
+ alu_b_src <= 2'b01;
+ alu_ctrl <= 1'b1;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s02_mem_addr: begin
- alu_a_src <= 2'b10;
- alu_b_src <= 2'b01;
- alu_ctrl <= 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b10;
+ alu_b_src <= 2'b01;
+ alu_ctrl <= 1'b1;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s03_mem_read: begin
- result_src <= 2'b00;
mem_addr_src <= 1'b1;
+ alu_a_src <= 2'b00;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s04_mem_wb: begin
- result_src <= 2'b01;
- rf_we = 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b00;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b01;
+ mem_we <= 1'b0;
+ rf_we <= 1'b1;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s05_mem_write: begin
- result_src <= 2'b00;
mem_addr_src <= 1'b1;
- mem_we = 1'b1;
+ alu_a_src <= 2'b00;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b1;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s06_execute_r: begin
- alu_a_src <= 2'b10;
- alu_b_src <= 2'b00;
- alu_ctrl <= 1'b0;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b10;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s07_alu_wb: begin
- result_src <= 2'b00;
- rf_we = 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b00;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b1;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s08_execute_i: begin
- alu_a_src <= 2'b10;
- alu_b_src <= 2'b01;
- alu_ctrl <= 1'b0;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b10;
+ alu_b_src <= 2'b01;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
s09_jal: begin
- alu_a_src <= 2'b01;
- alu_b_src <= 2'b10;
- alu_ctrl <= 1'b1;
- result_src <= 2'b00;
- pc_update = 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b01;
+ alu_b_src <= 2'b10;
+ alu_ctrl <= 1'b1;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b1;
+ branch <= 1'b0;
end
s10_jalr: begin
- alu_a_src <= 2'b10;
- alu_b_src <= 2'b01;
- alu_ctrl <= 1'b1;
- result_src <= 2'b10;
- pc_update = 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b10;
+ alu_b_src <= 2'b01;
+ alu_ctrl <= 1'b1;
+ result_src <= 2'b10;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b1;
+ branch <= 1'b0;
end
s11_br: begin
- alu_a_src <= 2'b10;
- alu_b_src <= 2'b00;
- alu_ctrl <= 1'b0;
- result_src <= 2'b00;
- branch = 1'b1;
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b10;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b1;
+ end
+ default: begin
+ mem_addr_src <= 1'b0;
+ alu_a_src <= 2'b00;
+ alu_b_src <= 2'b00;
+ alu_ctrl <= 1'b0;
+ result_src <= 2'b00;
+ mem_we <= 1'b0;
+ rf_we <= 1'b0;
+ instr_we <= 1'b0;
+ pc_update <= 1'b0;
+ branch <= 1'b0;
end
endcase
end
diff --git a/src/cpu.v b/src/cpu.v
index 66ae8ce..b1c28a1 100644
--- a/src/cpu.v
+++ b/src/cpu.v
@@ -1,28 +1,14 @@
module cpu (
input clk,
- input rst
+ input rstn
);
-// Control Unit
-
-wire mem_addr_src;
-wire mem_we;
-wire pc_we;
-wire instr_we;
-wire rf_we;
-wire alu_zero;
-wire [3:0] alu_op;
-wire [1:0] alu_a_src;
-wire [1:0] alu_b_src;
-wire [1:0] result_src;
-
-control_unit cu (
+control_unit control_unit (
.clk(clk),
- .rst(rst),
- .opcode(opcode),
- .funct3(funct3),
- .funct7(funct7),
+ .rstn(rstn),
+ .instr(instr),
+ .imm_src(imm_src),
.alu_zero(alu_zero),
.pc_we(pc_we),
.mem_addr_src(mem_addr_src),
@@ -35,146 +21,153 @@ control_unit cu (
.rf_we(rf_we)
);
-// Fetch
-reg [31:0] pc;
+wire [31:0] pc, pc_buf;
+
+wire [31:0] mem_addr;
+
+wire mem_addr_src;
+
+wire [31:0] mem_rd;
+
+wire mem_we;
+wire instr_we;
+
+wire [31:0] instr;
+
+wire [31:0] data_buf;
+wire pc_we;
+
+wire rf_we;
+
+wire [31:0] rd1, rd2;
+wire [31:0] rd1_buf, rd2_buf;
+
+wire [31:0] alu_a, alu_b;
+
+wire [31:0] imm;
+wire [2:0] imm_src;
+
+wire [1:0] alu_a_src;
+wire [1:0] alu_b_src;
+
+wire [3:0] alu_op;
+
+wire [31:0] alu_result;
+wire alu_zero;
+
+wire [31:0] alu_result_buf;
+
+wire [1:0] result_src;
+
+wire [31:0] result;
-always @ (posedge clk or posedge rst) begin
- if (rst) pc <= 32'h0001_0000;
- else if (pc_we) pc <= result;
-end
-wire [31:0] mem_addr = mem_addr_src ? result : pc;
+pc_reg pc_reg (
+ .clk(clk),
+ .rstn(rstn),
+ .we(pc_we),
+ .pc_in(result),
+ .pc(pc)
+);
-wire [31:0] mem_read_data;
+mem_addr_src_mux mem_addr_src_mux (
+ .src_pc(pc),
+ .src_result(result),
+ .mem_addr_src(mem_addr_src),
+ .mem_addr(mem_addr)
+);
-memory_unit mu (
+memory_interface memory_interface (
.clk(clk),
- .rst(rst),
+ .rstn(rstn),
.we(mem_we),
.addr(mem_addr),
- .read_data(mem_read_data),
- .write_data(b_buf)
+ .rd(mem_rd),
+ .wd(rd2_buf)
);
-reg [31:0] instruction;
-reg [31:0] pc_buf;
-
-always @ (posedge clk or posedge rst) begin
- if (rst) begin
- pc_buf <= 32'b0;
- instruction <= 32'b0;
- end else begin
- if (instr_we) begin
- pc_buf <= pc;
- instruction <= mem_read_data;
- end
- end
-end
-
-reg [31:0] data;
-
-always @(posedge clk or posedge rst) begin
- if (rst) data <= 32'b0;
- else data <= mem_read_data;
-end
-
-// Instruction Decode
-
-wire [6:0] opcode;
-wire [2:0] funct3;
-wire [6:0] funct7;
-wire [31:0] immediate;
-wire [4:0] rs1, rs2, rd;
-
-instruction_decode id (
- .instruction(instruction),
- .opcode(opcode),
- .funct3(funct3),
- .funct7(funct7),
- .immediate(immediate),
- .rs1(rs1),
- .rs2(rs2),
- .rd(rd)
+instruction_reg instruction_reg (
+ .clk(clk),
+ .rstn(rstn),
+ .we(instr_we),
+ .pc_in(pc),
+ .instr_in(mem_rd),
+ .pc_buf(pc_buf),
+ .instr(instr)
);
-// Register File
+data_reg data_reg (
+ .clk(clk),
+ .rstn(rstn),
+ .data_in(mem_rd),
+ .data_buf(data_buf)
+);
-wire [31:0] rs1_data, rs2_data;
+immediate_extend immediate_extend (
+ .instr(instr),
+ .imm_src(imm_src),
+ .imm(imm)
+);
-register_file rf (
+register_file register_file (
.clk(clk),
- .rst(rst),
+ .rstn(rstn),
.we(rf_we),
- .rs1(rs1),
- .rs2(rs2),
- .rd(rd),
- .rs1_data(rs1_data),
- .rs2_data(rs2_data),
- .rd_data(result)
+ .ra1(instr[19:15]),
+ .ra2(instr[24:20]),
+ .wa3(instr[11:7]),
+ .rd1(rd1),
+ .rd2(rd2),
+ .wd3(result)
);
-reg [31:0] a_buf, b_buf;
-
-always @ (posedge clk or posedge rst) begin
- if (rst) begin
- a_buf <= 32'b0;
- b_buf <= 32'b0;
- end else begin
- a_buf <= rs1_data;
- b_buf <= rs2_data;
- end
-end
-
-// Execute
+register_file_reg register_file_reg (
+ .clk(clk),
+ .rstn(rstn),
+ .rd1_in(rd1),
+ .rd2_in(rd2),
+ .rd1_buf(rd1_buf),
+ .rd2_buf(rd2_buf)
+);
-reg [31:0] a, b;
-wire [31:0] alu_result;
+alu_a_src_mux alu_a_src_mux(
+ .src_pc(pc),
+ .src_pc_buf(pc_buf),
+ .src_rd1_buf(rd1_buf),
+ .alu_a_src(alu_a_src),
+ .alu_a(alu_a)
+);
-always @ (*) begin
- case(alu_a_src)
- 2'b00: a <= pc;
- 2'b01: a <= pc_buf;
- 2'b10: a <= a_buf;
- default: a <= 32'b0;
- endcase
-end
-
-always @ (*) begin
- case(alu_b_src)
- 2'b00: b <= b_buf;
- 2'b01: b <= immediate;
- 2'b10: b <= 32'h4;
- default: b <= 32'b0;
- endcase
-end
+alu_b_src_mux alu_b_src_mux (
+ .src_rd2_buf(rd2_buf),
+ .src_imm(imm),
+ .alu_b_src(alu_b_src),
+ .alu_b(alu_b)
+);
alu alu (
- .a(a),
- .b(b),
+ .a(alu_a),
+ .b(alu_b),
.op(alu_op),
.result(alu_result),
.zero(alu_zero)
);
-reg [31:0] result_buf;
-
-always @ (posedge clk or posedge rst) begin
- if (rst) result_buf <= 32'b0;
- else result_buf <= alu_result;
-end
-
-// Writeback
+alu_result_reg alu_result_reg (
+ .clk(clk),
+ .rstn(rstn),
+ .alu_result_in(alu_result),
+ .alu_result_buf(alu_result_buf)
+);
-reg [31:0] result;
+result_mux result_mux (
+ .src_alu_result_buf(alu_result_buf),
+ .src_alu_result(alu_result),
+ .src_data_buf(data_buf),
+ .result_src(result_src),
+ .result(result)
+);
-always @ (*) begin
- case(result_src)
- 2'b00: result <= result_buf;
- 2'b01: result <= data;
- 2'b10: result <= alu_result;
- default: result <= 32'b0;
- endcase
-end
endmodule
diff --git a/src/data_reg.v b/src/data_reg.v
new file mode 100644
index 0000000..f7530e2
--- /dev/null
+++ b/src/data_reg.v
@@ -0,0 +1,13 @@
+module data_reg (
+ input clk,
+ input rstn,
+ input [31:0] data_in,
+ output reg [31:0] data_buf
+);
+
+always @ (posedge clk) begin
+ if (!rstn) data_buf <= 32'b0;
+ else data_buf <= data_in;
+end
+
+endmodule
diff --git a/src/immediate_extend.v b/src/immediate_extend.v
new file mode 100644
index 0000000..749cf2b
--- /dev/null
+++ b/src/immediate_extend.v
@@ -0,0 +1,20 @@
+module immediate_extend (
+ input [31:0] instr,
+ input [2:0] imm_src,
+ output reg [31:0] imm
+);
+
+
+always @ (*) begin
+ case (imm_src)
+ 3'b010: imm <= { {21{instr[31]}}, instr[30:20] }; // I
+ 3'b011: imm <= { {21{instr[31]}}, instr[30:25], instr[11:7] }; // S
+ 3'b100: imm <= { {20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0 }; // B
+ 3'b101: imm <= { instr[31:12], 12'b0 }; // U
+ 3'b110: imm <= { {12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 }; // J
+ default: imm <= 32'b0; // Unknown
+ endcase
+end
+
+
+endmodule
diff --git a/src/instruction_reg.v b/src/instruction_reg.v
new file mode 100644
index 0000000..f3f456e
--- /dev/null
+++ b/src/instruction_reg.v
@@ -0,0 +1,17 @@
+module instruction_reg (
+ input clk, rstn, we,
+ input [31:0] pc_in, instr_in,
+ output reg [31:0] pc_buf, instr
+);
+
+always @ (posedge clk) begin
+ if (!rstn) begin
+ pc_buf <= 32'b0;
+ instr <= 32'b0;
+ end else if (we) begin
+ pc_buf <= pc_in;
+ instr <= instr_in;
+ end
+end
+
+endmodule
diff --git a/src/led_unit.v b/src/led_unit.v
new file mode 100644
index 0000000..cfcbbdf
--- /dev/null
+++ b/src/led_unit.v
@@ -0,0 +1,18 @@
+module led_unit (
+ input clk,
+ input rst,
+ input we,
+ output reg [31:0] data_read,
+ input [31:0] data_write,
+ output [5:0] led_output
+);
+
+assign led_output = ~data_read[5:0];
+
+always @(posedge clk or posedge rst) begin
+ if (rst) data_read <= 32'b0;
+ else if (we) data_read <= data_write;
+ else data_read <= data_read;
+end
+
+endmodule
diff --git a/src/mem_addr_src_mux.v b/src/mem_addr_src_mux.v
new file mode 100644
index 0000000..a415287
--- /dev/null
+++ b/src/mem_addr_src_mux.v
@@ -0,0 +1,15 @@
+module mem_addr_src_mux (
+ input [31:0] src_pc, src_result,
+ input mem_addr_src,
+ output reg [31:0] mem_addr
+);
+
+always @(*) begin
+ case (mem_addr_src)
+ 1'b0: mem_addr <= src_pc;
+ 1'b1: mem_addr <= src_result;
+ default: mem_addr <= 32'b0;
+ endcase
+end
+
+endmodule
diff --git a/src/memory_unit.v b/src/memory_interface.v
index 6e2b457..0b89e39 100644
--- a/src/memory_unit.v
+++ b/src/memory_interface.v
@@ -1,10 +1,10 @@
-module memory_unit (
+module memory_interface (
input clk,
- input rst,
+ input rstn,
input we,
input [31:0] addr,
- output reg [31:0] read_data,
- input [31:0] write_data
+ output reg [31:0] rd,
+ input [31:0] wd
);
reg ram_we;
@@ -12,11 +12,11 @@ wire [31:0] ram_read_data, rom_read_data;
ram #(.N(32), .SIZE(1024)) ram(
.clk(clk),
- .rst(rst),
+ .rst(!rstn),
.we(ram_we),
.addr(addr),
.data_read(ram_read_data),
- .data_write(write_data)
+ .data_write(wd)
);
rom #(.N(32), .SIZE(1024)) rom(
@@ -25,6 +25,7 @@ rom #(.N(32), .SIZE(1024)) rom(
.data_read(rom_read_data)
);
+
// 0000 0000 Reserved
// 0000 FFFF
//
@@ -39,16 +40,18 @@ rom #(.N(32), .SIZE(1024)) rom(
always @(*) begin
- ram_we = 0;
- if (addr[31:16] == 16'h0000) begin
- read_data <= 0;
- end else if (addr[31:16] >= 16'h0001 && addr[31:16] <= 16'h000F) begin
- read_data <= rom_read_data;
+ if (addr[31:16] >= 16'h0001 && addr[31:16] <= 16'h000F) begin
+ ram_we <= 0;
+ rd <= rom_read_data;
end else if (addr[31:16] >= 16'h0010 && addr[31:16] <= 16'hFF0F) begin
- ram_we = we;
- read_data <= ram_read_data;
+ ram_we <= we;
+ rd <= ram_read_data;
end else if (addr[31:16] >= 16'hFF10 && addr[31:16] <= 16'hFFFF) begin
- read_data <= 0;
+ ram_we <= 0;
+ rd <= 0;
+ end else begin
+ ram_we <= 0;
+ rd <= 0;
end
end
diff --git a/src/pc_reg.v b/src/pc_reg.v
new file mode 100644
index 0000000..9d7600b
--- /dev/null
+++ b/src/pc_reg.v
@@ -0,0 +1,18 @@
+module pc_reg (
+ input clk,
+ input rstn,
+ input we,
+ input [31:0] pc_in,
+ output reg [31:0] pc
+);
+
+
+parameter PC_INITIAL = 32'h0001_0000;
+
+
+always @ (posedge clk) begin
+ if (!rstn) pc <= PC_INITIAL;
+ else if (we) pc <= pc_in;
+end
+
+endmodule
diff --git a/src/ram.v b/src/ram.v
index efcfc04..1573de8 100644
--- a/src/ram.v
+++ b/src/ram.v
@@ -17,17 +17,10 @@ reg [8:0] memory [SIZE-1:0];
assign data_read = { memory[addr + 3], memory[addr + 2], memory[addr + 1], memory[addr + 0] };
-// integer i;
always @(posedge clk /*or posedge rst*/) begin
-// if (rst) begin
-// for (i = 0; i < SIZE; i = i + 1)
-// memory[i] <= 0;
-// end else begin
- if (we) begin
- { memory[addr + 3], memory[addr + 2], memory[addr + 1], memory[addr + 0] } = data_write;
- end
-// end
-
+ if (we) begin
+ { memory[addr + 3], memory[addr + 2], memory[addr + 1], memory[addr + 0] } = data_write;
+ end
end
endmodule
diff --git a/src/register_file.v b/src/register_file.v
index 11c36fe..9c8f431 100644
--- a/src/register_file.v
+++ b/src/register_file.v
@@ -1,12 +1,11 @@
module register_file (
- input clk, rst, we,
- input [4:0] rs1, rs2, rd,
- input [31:0] rd_data,
- output reg [31:0] rs1_data, rs2_data
+ input clk, rstn, we,
+ input [4:0] ra1, ra2, wa3,
+ input [31:0] wd3,
+ output [31:0] rd1, rd2
);
-
-reg [31:0] registers[31:1];
+reg [31:0] regs[31:1];
// For debugging purposes:
wire [31:0] reg_x0_zero,
@@ -42,52 +41,45 @@ wire [31:0] reg_x0_zero,
reg_x30_t5,
reg_x31_t6;
-assign reg_x0_zero = 32'b0;
-assign reg_x1_ra = registers[1];
-assign reg_x2_sp = registers[2];
-assign reg_x3_gp = registers[3];
-assign reg_x4_tp = registers[4];
-assign reg_x5_t0 = registers[5];
-assign reg_x6_t1 = registers[6];
-assign reg_x7_t2 = registers[7];
-assign reg_x8_s0_fp = registers[8];
-assign reg_x9_s1 = registers[9];
-assign reg_x10_a0 = registers[10];
-assign reg_x11_a1 = registers[11];
-assign reg_x12_a2 = registers[12];
-assign reg_x13_a3 = registers[13];
-assign reg_x14_a4 = registers[14];
-assign reg_x15_a5 = registers[15];
-assign reg_x16_a6 = registers[16];
-assign reg_x17_a7 = registers[17];
-assign reg_x18_s2 = registers[18];
-assign reg_x19_s3 = registers[19];
-assign reg_x20_s4 = registers[20];
-assign reg_x21_s5 = registers[21];
-assign reg_x22_s6 = registers[22];
-assign reg_x23_s7 = registers[23];
-assign reg_x24_s8 = registers[24];
-assign reg_x25_s9 = registers[25];
-assign reg_x26_s10 = registers[26];
-assign reg_x27_s11 = registers[27];
-assign reg_x28_t3 = registers[28];
-assign reg_x29_t4 = registers[29];
-assign reg_x30_t5 = registers[30];
-assign reg_x31_t6 = registers[31];
-
+assign reg_x0_zero = 32'b0;
+assign reg_x1_ra = regs[1];
+assign reg_x2_sp = regs[2];
+assign reg_x3_gp = regs[3];
+assign reg_x4_tp = regs[4];
+assign reg_x5_t0 = regs[5];
+assign reg_x6_t1 = regs[6];
+assign reg_x7_t2 = regs[7];
+assign reg_x8_s0_fp = regs[8];
+assign reg_x9_s1 = regs[9];
+assign reg_x10_a0 = regs[10];
+assign reg_x11_a1 = regs[11];
+assign reg_x12_a2 = regs[12];
+assign reg_x13_a3 = regs[13];
+assign reg_x14_a4 = regs[14];
+assign reg_x15_a5 = regs[15];
+assign reg_x16_a6 = regs[16];
+assign reg_x17_a7 = regs[17];
+assign reg_x18_s2 = regs[18];
+assign reg_x19_s3 = regs[19];
+assign reg_x20_s4 = regs[20];
+assign reg_x21_s5 = regs[21];
+assign reg_x22_s6 = regs[22];
+assign reg_x23_s7 = regs[23];
+assign reg_x24_s8 = regs[24];
+assign reg_x25_s9 = regs[25];
+assign reg_x26_s10 = regs[26];
+assign reg_x27_s11 = regs[27];
+assign reg_x28_t3 = regs[28];
+assign reg_x29_t4 = regs[29];
+assign reg_x30_t5 = regs[30];
+assign reg_x31_t6 = regs[31];
+
+
+assign rd1 = ra1 == 0 ? 32'b0 : regs[ra1];
+assign rd2 = ra2 == 0 ? 32'b0 : regs[ra2];
-// integer i;
-always @(posedge clk /*or rst*/) begin
-// if (rst) begin
-// for (i = 1; i < 32; i = i + 1)
-// registers[i] <= 32'b0;
-// end else begin
- rs1_data = (rs1 == 0) ? 32'b0 : registers[rs1];
- rs2_data = (rs2 == 0) ? 32'b0 : registers[rs2];
- if (we && (rd != 0)) begin
- registers[rd] <= rd_data;
- end
-// end
+always @ (posedge clk) begin
+ if (we && (wa3 != 0)) regs[wa3] = wd3;
end
endmodule
diff --git a/src/register_file_reg.v b/src/register_file_reg.v
new file mode 100644
index 0000000..0536110
--- /dev/null
+++ b/src/register_file_reg.v
@@ -0,0 +1,17 @@
+module register_file_reg (
+ input clk, rstn,
+ input [31:0] rd1_in, rd2_in,
+ output reg [31:0] rd1_buf, rd2_buf
+);
+
+always @ (posedge clk) begin
+ if (!rstn) begin
+ rd1_buf <= 32'b0;
+ rd2_buf <= 32'b0;
+ end else begin
+ rd1_buf <= rd1_in;
+ rd2_buf <= rd2_in;
+ end
+end
+
+endmodule
diff --git a/src/result_mux.v b/src/result_mux.v
new file mode 100644
index 0000000..9b6cf06
--- /dev/null
+++ b/src/result_mux.v
@@ -0,0 +1,16 @@
+module result_mux (
+ input [31:0] src_alu_result_buf, src_alu_result, src_data_buf,
+ input [1:0] result_src,
+ output reg [31:0] result
+);
+
+always @(*) begin
+ case (result_src)
+ 2'b00: result <= src_alu_result_buf;
+ 2'b01: result <= src_data_buf;
+ 2'b10: result <= src_alu_result;
+ default: result <= 32'b0;
+ endcase
+end
+
+endmodule
diff --git a/src/top.v b/src/top.v
index 37e33d7..e5a6381 100644
--- a/src/top.v
+++ b/src/top.v
@@ -1,36 +1,20 @@
module top (
input clk,
input key
- //output [5:0] led
);
-wire rst;
-assign rst = ~key;
+wire rstn, clk_cpu;
+assign rstn = key;
-cpu cpu (
- .clk(clk),
- .rst(rst)
+clock_divider #(.N(1024 * 1024)) clkdiv (
+ .clk(clk),
+ .reset(!rstn),
+ .clk_out(clk_cpu)
);
-/*
-
-reg [5:0] ctr_q;
-wire [5:0] ctr_d;
-wire clk_slow;
-assign reset = ~key;
-
-clock_divider #(.N(10000000)) clk_div (
- .clk(clk),
- .clk_out(clk_slow),
- .reset(reset)
+cpu cpu (
+ .clk(clk_cpu),
+ .rstn(rstn)
);
-always @(posedge clk_slow) begin
- if (key) ctr_q <= ctr_d;
- else ctr_q <= 6'b0;
-end
-
-assign ctr_d = ctr_q + 6'b1;
-assign led = ~ctr_q;
-*/
endmodule