M src/control_unit.sv => src/control_unit.sv +5 -1
@@ 35,7 35,9 @@ module control_unit(
// alu or memory
output reg_rd_source_t reg_rd_src,
output [4:0] reg_rd,
- output reg_we
+ output reg_we,
+
+ output ebreak
);
wire use_immediate;
@@ 54,6 56,8 @@ module control_unit(
instruction_decoder decoder(
.instruction(instruction),
+ .ebreak(ebreak),
+
.store_memory(memory_we),
.load_memory(load_memory),
M src/cpu.sv => src/cpu.sv +17 -10
@@ 13,7 13,9 @@ module cpu(
input [31:0] memory_out,
output reg [31:0] memory_write,
output [3:0] memory_byte_enable,
- output reg memory_we
+ output reg memory_we,
+
+ output ebreak
);
parameter WIDTH = 32;
@@ 92,15 94,18 @@ module cpu(
// pc source
assign jump_taken = jump_instruction && (alu_zero ^ jump_negate_zero);
always_comb begin
- case (pc_src)
- PC_PLUS : begin
- if (jump_taken)
- pc_next = pc + immediate;
- else
- pc_next = pc + 4;
- end
- PC_ALU : pc_next = alu_out;
- endcase
+ if (ebreak)
+ pc_next = pc;
+ else
+ case (pc_src)
+ PC_PLUS : begin
+ if (jump_taken)
+ pc_next = pc + immediate;
+ else
+ pc_next = pc + 4;
+ end
+ PC_ALU : pc_next = alu_out;
+ endcase
end
// register file write source
@@ 117,6 122,8 @@ module cpu(
control_unit control_unit_inst(
.instruction(instruction),
+ .ebreak(ebreak),
+
.immediate(immediate),
.alu_op(alu_op),
M src/instruction_decoder.sv => src/instruction_decoder.sv +8 -1
@@ 47,7 47,9 @@ module instruction_decoder(
output [4:0] reg_rs1,
output reg [4:0] reg_rs2,
output [4:0] reg_rd,
- output reg_we
+ output reg_we,
+
+ output reg ebreak
);
typedef enum bit[2:0] {Unknown, R, I, S, SB, U, UJ} instruction_type_type;
instruction_type_type instruction_type;
@@ 199,6 201,7 @@ module instruction_decoder(
reg_we = 1'b1;
conditional_jump = 1'b0;
unconditional_jump = 1'b0;
+ ebreak = 1'b0;
// TODO: multiplication
// NOTE: ecall, ebreak, CSRRW, CSRRS, SCRRC, CSRRWI, CSRRSI, CSRRCI unsupported
@@ 232,6 235,10 @@ module instruction_decoder(
load_pc = 1'b1;
reg_we = 1'b1;
end
+ 5'b11100 : begin
+ if (funct3 == 3'b0)
+ ebreak = 1'b1;
+ end
default : ;
endcase;
end;
M testbench/tb_cpu_add.sv => testbench/tb_cpu_add.sv +9 -3
@@ 11,6 11,8 @@ module tb_cpu_add();
wire [31:0] pc;
reg [31:0] instruction;
+ wire ebreak;
+
cpu uut(
.clk(clk),
.rst_n(rst_n),
@@ 22,7 24,9 @@ module tb_cpu_add();
.memory_out(memory_out),
.memory_write(memory_write),
.memory_byte_enable(memory_write_byte_enable),
- .memory_we(memory_we)
+ .memory_we(memory_we),
+
+ .ebreak(ebreak)
);
ram memory_inst(
@@ 39,6 43,10 @@ module tb_cpu_add();
.instruction(instruction)
);
+ always_ff @ (posedge ebreak) begin
+ #15 $finish;
+ end
+
initial begin
clk = 0;
forever #5 clk = ~clk;
@@ 51,7 59,5 @@ module tb_cpu_add();
rst_n = 0;
#20
rst_n = 1;
-
- #500 $finish;
end
endmodule
M testbench/tb_cpu_branches.sv => testbench/tb_cpu_branches.sv +9 -3
@@ 10,6 10,8 @@ module tb_cpu_branches();
wire [31:0] pc;
reg [31:0] instruction;
+ wire ebreak;
+
cpu uut(
.clk(clk),
.rst_n(rst_n),
@@ 21,7 23,9 @@ module tb_cpu_branches();
.memory_out(memory_out),
.memory_write(memory_write),
.memory_byte_enable(memory_write_byte_enable),
- .memory_we(memory_we)
+ .memory_we(memory_we),
+
+ .ebreak(ebreak)
);
ram memory_inst(
@@ 38,6 42,10 @@ module tb_cpu_branches();
.instruction(instruction)
);
+ always_ff @ (posedge ebreak) begin
+ #15 $finish;
+ end
+
initial begin
clk = 0;
forever #5 clk = ~clk;
@@ 50,7 58,5 @@ module tb_cpu_branches();
rst_n = 0;
#20
rst_n = 1;
-
- #500 $finish;
end
endmodule
M testbench/tb_cpu_gcd.sv => testbench/tb_cpu_gcd.sv +9 -3
@@ 10,6 10,8 @@ module tb_cpu_gcd();
wire [31:0] pc;
reg [31:0] instruction;
+ wire ebreak;
+
cpu uut(
.clk(clk),
.rst_n(rst_n),
@@ 21,7 23,9 @@ module tb_cpu_gcd();
.memory_out(memory_out),
.memory_write(memory_write),
.memory_byte_enable(memory_write_byte_enable),
- .memory_we(memory_we)
+ .memory_we(memory_we),
+
+ .ebreak(ebreak)
);
ram memory_inst(
@@ 38,6 42,10 @@ module tb_cpu_gcd();
.instruction(instruction)
);
+ always_ff @ (posedge ebreak) begin
+ #15 $finish;
+ end
+
initial begin
clk = 0;
forever #5 clk = ~clk;
@@ 50,7 58,5 @@ module tb_cpu_gcd();
rst_n = 0;
#20
rst_n = 1;
-
- #5000 $finish;
end
endmodule
M testbench/tb_cpu_simple.sv => testbench/tb_cpu_simple.sv +9 -3
@@ 11,6 11,8 @@ module tb_cpu_simple();
wire [31:0] pc;
reg [31:0] instruction;
+ wire ebreak;
+
cpu uut(
.clk(clk),
.rst_n(rst_n),
@@ 22,7 24,9 @@ module tb_cpu_simple();
.memory_out(memory_out),
.memory_write(memory_write),
.memory_byte_enable(memory_write_byte_enable),
- .memory_we(memory_we)
+ .memory_we(memory_we),
+
+ .ebreak(ebreak)
);
ram memory_inst(
@@ 34,6 38,10 @@ module tb_cpu_simple();
.rd(memory_out)
);
+ always_ff @ (posedge ebreak) begin
+ #15 $finish;
+ end
+
always_comb begin
case(pc[5:2])
// addi x2, x0, 30
@@ 92,7 100,5 @@ module tb_cpu_simple();
rst_n = 0;
#20
rst_n = 1;
-
- #300 $finish;
end
endmodule
M testbench/tb_cpu_tests.sv => testbench/tb_cpu_tests.sv +9 -3
@@ 10,6 10,8 @@ module tb_cpu_tests();
wire [31:0] pc;
reg [31:0] instruction;
+ wire ebreak;
+
cpu uut(
.clk(clk),
.rst_n(rst_n),
@@ 21,7 23,9 @@ module tb_cpu_tests();
.memory_out(memory_out),
.memory_write(memory_write),
.memory_byte_enable(memory_write_byte_enable),
- .memory_we(memory_we)
+ .memory_we(memory_we),
+
+ .ebreak(ebreak)
);
ram memory_inst(
@@ 38,6 42,10 @@ module tb_cpu_tests();
.instruction(instruction)
);
+ always_ff @ (posedge ebreak) begin
+ #15 $finish;
+ end
+
initial begin
clk = 0;
forever #5 clk = ~clk;
@@ 50,7 58,5 @@ module tb_cpu_tests();
rst_n = 0;
#20
rst_n = 1;
-
- #500 $finish;
end
endmodule