From b3fd2a827dd74fb674eef2ba7a388d5670a9b800 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Fri, 20 Oct 2023 18:48:18 +0900 Subject: [PATCH 01/17] Add: basic element for risc-v single cycle cpu --- rtl/alu.v | 23 ++++++++++++---- rtl/decoder.v | 19 +++++++++++++ rtl/instruction.v | 8 ++++++ rtl/memory.v | 18 +++++++++++++ rtl/mux2_1.v | 7 +++++ rtl/mux4_1.v | 8 ++++++ rtl/program_counter.v | 12 +++++++++ rtl/registers_bank.v | 18 +++++++++++++ scripts/gen_simu_do.sh | 2 -- tb/tb_alu.v | 44 +++++++++++++++++++++++++++--- tb/tb_mux2_1.v | 61 ++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 rtl/decoder.v create mode 100644 rtl/instruction.v create mode 100644 rtl/memory.v create mode 100644 rtl/mux2_1.v create mode 100644 rtl/mux4_1.v create mode 100644 rtl/program_counter.v create mode 100644 rtl/registers_bank.v create mode 100644 tb/tb_mux2_1.v diff --git a/rtl/alu.v b/rtl/alu.v index 5ecee99..9607a2c 100644 --- a/rtl/alu.v +++ b/rtl/alu.v @@ -1,6 +1,19 @@ -module alu (S, A, B); - output [31:0] S; - input [31:0] A, B; +module alu (input [31:0] input_a, input_b, + input [2:0] op_code, + output reg [31:0] out); + + always@ (*) begin + case (op_code) + 3'b000 : out <= input_a + input_b; + 3'b001 : out <= input_a << input_b; + 3'b010 : out <= (input_a < input_b) ? 1 : 0; + 3'b011 : out <= input_a ^ input_b; + 3'b100 : out <= input_a >> input_b; + 3'b101 : out <= input_a >>> input_b; + 3'b110 : out <= input_a | input_b; + 3'b111 : out <= input_a & input_b; + default : out <= 32'b0; + endcase + end - xor N[31:0] (S, A, B); -endmodule \ No newline at end of file +endmodule diff --git a/rtl/decoder.v b/rtl/decoder.v new file mode 100644 index 0000000..ffc8254 --- /dev/null +++ b/rtl/decoder.v @@ -0,0 +1,19 @@ +module decoder (input [31:0] instruction, + output immediate, + output we_reg, adder_pc, + output [1:0] input_reg, + output [4:0] select_a, select_b, select_d, + output source_alu, + output [2:0] op_code_alu, + output mem_we, + output [31:0] mem_address + output jmp_pc, b_pc); + + always @(*) begin + if (reset == 1) + registers[0] <= 32'b0; + else if (we == 1) + registers[select_d] <= input_d; + end + +endmodule diff --git a/rtl/instruction.v b/rtl/instruction.v new file mode 100644 index 0000000..a91d9fb --- /dev/null +++ b/rtl/instruction.v @@ -0,0 +1,8 @@ +module instruction (input [31:0] address, + output [31:0] instruction); + + reg [63:0] memory [31:0]; + + assign instruction = memory[address]; + +endmodule diff --git a/rtl/memory.v b/rtl/memory.v new file mode 100644 index 0000000..a19b913 --- /dev/null +++ b/rtl/memory.v @@ -0,0 +1,18 @@ +module instruction (input clock, reset, + input we, + input [31:0] address, + input [31:0] data_in + output [31:0] data_out); + + reg [63:0] memory [31:0]; + + always @(posedge clock, reset) begin + if (reset == 1) + memory[0] <= 32'b0; + else if (we == 1) + memory[address] <= data_in; + end + + assign data_out = memory[address]; + +endmodule diff --git a/rtl/mux2_1.v b/rtl/mux2_1.v new file mode 100644 index 0000000..3711974 --- /dev/null +++ b/rtl/mux2_1.v @@ -0,0 +1,7 @@ +module mux2_1 (input [31:0] A, B, + input S, + output [31:0] O); + + assign O = S ? B : A; + +endmodule \ No newline at end of file diff --git a/rtl/mux4_1.v b/rtl/mux4_1.v new file mode 100644 index 0000000..80c50ab --- /dev/null +++ b/rtl/mux4_1.v @@ -0,0 +1,8 @@ +module mux4_1 (input [31:0] A, B, C, D, + input [1:0] S, + output [31:0] O); + + assign O = S[0] ? (S[1] ? D : C) + : (S[1] ? B : A); + +endmodule diff --git a/rtl/program_counter.v b/rtl/program_counter.v new file mode 100644 index 0000000..c9dfc65 --- /dev/null +++ b/rtl/program_counter.v @@ -0,0 +1,12 @@ +module program_counter (input clock, reset, + input [31:0] new_pc, + output reg [31:0] pc); + + always @ (posedge clock, reset) begin + if (reset == 1) + pc <= 32'b0; + else + pc <= new_pc; + end + +endmodule diff --git a/rtl/registers_bank.v b/rtl/registers_bank.v new file mode 100644 index 0000000..3af16b2 --- /dev/null +++ b/rtl/registers_bank.v @@ -0,0 +1,18 @@ +module registers_bank (input clock, reset, we, + input [4:0] select_d, select_a, select_b, + input [31:0] input_d, + output [31:0] output_a, output_b); + + reg [31:0] registers[31:0]; + + always @(posedge clock, reset) begin + if (reset == 1) + registers[0] <= 32'b0; + else if (we == 1) + registers[select_d] <= input_d; + end + + assign output_a = registers[select_a]; + assign output_b = registers[select_b]; + +endmodule diff --git a/scripts/gen_simu_do.sh b/scripts/gen_simu_do.sh index 09aecb4..60f3f94 100755 --- a/scripts/gen_simu_do.sh +++ b/scripts/gen_simu_do.sh @@ -33,5 +33,3 @@ add wave -radix unsigned *' >> ./sim/simu.do echo 'run -all' >> ./sim/simu.do exit 0 - -# CRC - Hamming Code diff --git a/tb/tb_alu.v b/tb/tb_alu.v index c07f90a..c9f80d9 100644 --- a/tb/tb_alu.v +++ b/tb/tb_alu.v @@ -1,3 +1,41 @@ -module tb_alu (S); - output [31:0] S; -endmodule \ No newline at end of file +`timescale 1ns / 1ps + +module tb_alu (); +// Design Inputs and outputs +reg [31:0] in_a; +reg [31:0] in_b; +reg [2:0] op_code; +wire [31:0] out; + +// DUT instantiation +alu alu ( + .input_a(in_a), + .input_b(in_b), + .op_code(op_code), + .out(out) +); + +// Test stimulus +initial begin + // Use the monitor task to display the FPGA IO + $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", + $time, in_a, in_b, op_code, out); + + // Generate each input with a 20 ns delay between them + in_a = 1'b0; + in_b = 1'b0; + op_code = 3'b000; + #20 + if (out !== 0) $display("[FAILED] output should be 0"); + in_a = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + in_b = 1'b1; + #20 + if (out !== 2) $display("[FAILED] output should be 2"); + op_code = 3'b001; + #20 + if (out !== 2) $display("[FAILED] output should be 2"); +end + +endmodule : tb_alu diff --git a/tb/tb_mux2_1.v b/tb/tb_mux2_1.v new file mode 100644 index 0000000..b36081f --- /dev/null +++ b/tb/tb_mux2_1.v @@ -0,0 +1,61 @@ +`timescale 1ns / 1ps + +module tb_mux2_1 (); +// Clock and reset signals +reg clk; +reg reset; + +// Design Inputs and outputs +reg [31:0] in_a; +reg [31:0] in_b; +reg ctrl; +wire [31:0] out; + +// DUT instantiation +mux2_1 mux ( + .S(ctrl), + .A(in_a), + .B(in_b), + .O(out) +); + +// generate the clock +initial begin + clk = 1'b0; + // forever #1 clk = ~clk; +end + +// Generate the reset +initial begin + reset = 1'b1; + #10 + reset = 1'b0; +end + +// Test stimulus +initial begin + // Use the monitor task to display the FPGA IO + $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", + $time, in_a, in_b, ctrl, out); + + // Generate each input with a 20 ns delay between them + in_a = 1'b0; + in_b = 1'b0; + ctrl = 1'b0; + #20 + if (out !== 0) $display("[FAILED] output should be 0"); + in_a = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + ctrl = 1'b1; + in_a = 1'b0; + in_b = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + ctrl = 1'b0; + in_a = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); +end + +endmodule : tb_mux2_1 -- 2.30.2 From f717284c477cf0ecd094b80e9b3cee5b53fff20a Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Sat, 21 Oct 2023 22:57:58 +0900 Subject: [PATCH 02/17] Add: assembly of risc-v cpu --- rtl/alu.v | 19 ++-- rtl/decoder.v | 250 ++++++++++++++++++++++++++++++++++++++++++--- rtl/memory.v | 4 +- rtl/mux2_1.v | 7 +- rtl/mux4_1.v | 7 +- rtl/risc-v_cpu.v | 0 rtl/risc_v_cpu.v | 127 +++++++++++++++++++++++ tb/tb_risc-v_cpu.v | 0 tb/tb_risc_v_cpu.v | 31 ++++++ 9 files changed, 415 insertions(+), 30 deletions(-) delete mode 100644 rtl/risc-v_cpu.v create mode 100644 rtl/risc_v_cpu.v delete mode 100644 tb/tb_risc-v_cpu.v create mode 100644 tb/tb_risc_v_cpu.v diff --git a/rtl/alu.v b/rtl/alu.v index 9607a2c..b159d3e 100644 --- a/rtl/alu.v +++ b/rtl/alu.v @@ -1,17 +1,18 @@ module alu (input [31:0] input_a, input_b, - input [2:0] op_code, + input [3:0] op_code, output reg [31:0] out); always@ (*) begin case (op_code) - 3'b000 : out <= input_a + input_b; - 3'b001 : out <= input_a << input_b; - 3'b010 : out <= (input_a < input_b) ? 1 : 0; - 3'b011 : out <= input_a ^ input_b; - 3'b100 : out <= input_a >> input_b; - 3'b101 : out <= input_a >>> input_b; - 3'b110 : out <= input_a | input_b; - 3'b111 : out <= input_a & input_b; + 4'b0000 : out <= input_a + input_b; + 4'b0001 : out <= input_a - input_b; + 4'b0010 : out <= input_a << input_b; + 4'b0011 : out <= (input_a < input_b) ? 1 : 0; + 4'b0100 : out <= input_a ^ input_b; + 4'b0101 : out <= input_a >> input_b; + 4'b0111 : out <= input_a >>> input_b; + 4'b1000 : out <= input_a | input_b; + 4'b1001 : out <= input_a & input_b; default : out <= 32'b0; endcase end diff --git a/rtl/decoder.v b/rtl/decoder.v index ffc8254..9312975 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -1,19 +1,243 @@ module decoder (input [31:0] instruction, - output immediate, - output we_reg, adder_pc, - output [1:0] input_reg, - output [4:0] select_a, select_b, select_d, - output source_alu, - output [2:0] op_code_alu, - output mem_we, - output [31:0] mem_address - output jmp_pc, b_pc); + output reg [31:0] immediate, + output reg we_reg, adder_pc, data_out, + output reg [1:0] input_reg, + output reg [4:0] select_a, select_b, select_d, + output reg source_alu, + output reg [3:0] op_code_alu, + output reg mem_we, + output reg [1:0] jmp_pc, + output reg b_pc, alu_not); + +function [3:0] get_op_code_alu(input [2:0] op_code, input arithmetic); + begin + case (op_code) + 3'b000 : get_op_code_alu = arithmetic ? 4'b0000 : 4'b0001; + 3'b001 : get_op_code_alu = 4'b0010; + 3'b010 : get_op_code_alu = 4'b0011; + 3'b011 : get_op_code_alu = 4'b0011; + 3'b100 : get_op_code_alu = 4'b0100; + 3'b101 : get_op_code_alu = arithmetic ? 4'b0101 : 4'b0111; + 3'b110 : get_op_code_alu = 4'b1000; + 3'b111 : get_op_code_alu = 4'b1010; + 3'b111 : get_op_code_alu = 4'b1011; + default : get_op_code_alu= 4'b0000; + endcase + end +endfunction + +function [3:0] get_op_code_alu_imm(input [2:0] op_code, input arithmetic); + begin + case (op_code) + 3'b000 : get_op_code_alu_imm = 4'b0000; + 3'b001 : get_op_code_alu_imm = 4'b0010; + 3'b010 : get_op_code_alu_imm = 4'b0011; + 3'b011 : get_op_code_alu_imm = 4'b0100; + 3'b100 : get_op_code_alu_imm = 4'b0101; + 3'b101 : get_op_code_alu_imm = arithmetic ? 4'b0111 : 4'b1000; + 3'b110 : get_op_code_alu_imm = 4'b1001; + 3'b111 : get_op_code_alu_imm = 4'b1010; + 3'b111 : get_op_code_alu_imm = 4'b1011; + default : get_op_code_alu_imm = 4'b0000; + endcase + end +endfunction + +function [3:0] branch_op_code(input [2:0] op_code); + begin + case (op_code) + 3'b000 : branch_op_code = 4'b0001; + 3'b001 : branch_op_code = 4'b0001; + 3'b010 : branch_op_code = 4'b0011; + 3'b011 : branch_op_code = 4'b0011; + 3'b100 : branch_op_code = 4'b0011; + 3'b101 : branch_op_code = 4'b0011; + default : branch_op_code = 4'b0000; + endcase + end +endfunction + +function branch_not(input [2:0] op_code); + begin + case (op_code) + 3'b000 : branch_not = 1; + 3'b001 : branch_not = 0; + 3'b010 : branch_not = 0; + 3'b011 : branch_not = 1; + 3'b100 : branch_not = 0; + 3'b101 : branch_not = 1; + default : branch_not = 0; + endcase + end +endfunction + + // TODO - Manage ALU OP CODE and IMM Extension + always @(*) begin - if (reset == 1) - registers[0] <= 32'b0; - else if (we == 1) - registers[select_d] <= input_d; + case (instruction[6:2]) + 5'b01100 : begin // OP - Add, ... + immediate = 0; + we_reg = 1; + adder_pc = 0; + data_out = 0; + input_reg = 2'b01; + select_a = instruction[19:15]; + select_b = instruction[24:20]; + select_d = instruction[11:7]; + source_alu = 0; + op_code_alu = get_op_code_alu(instruction[14:12], instruction[30]); + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + alu_not = 0; + end + 5'b00100 : begin // OP-IMM - Addi, ... + immediate = instruction[31:20]; + we_reg = 1; + adder_pc = 0; + data_out = 0; + input_reg = 2'b01; + select_a = instruction[19:15]; + select_b = 5'b00000; + select_d = instruction[11:7]; + source_alu = 1; + op_code_alu = get_op_code_alu_imm(instruction[14:12], instruction[30]); + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + end + 5'b00000 : begin // LOAD - Lw, ... + immediate = instruction[31:20]; + we_reg = 1; + adder_pc = 0; + data_out = 0; + input_reg = 2'b10; + select_a = instruction[19:15]; + select_b = 5'b00000; + select_d = instruction[11:7]; + source_alu = 1; + op_code_alu = 3'b000; + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + end + 5'b01000 : begin // STORE - Sw, ... + immediate = {instruction[31:25], instruction[11:7]}; + we_reg = 0; + adder_pc = 0; + data_out = 0; + input_reg = 2'b01; + select_a = instruction[19:15]; + select_b = instruction[24:20]; + select_d = 5'b00000; + source_alu = 1; + op_code_alu = 3'b000; + mem_we = 1; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + end + 5'b11000 : begin // BRANCH - Beq, ... + immediate = {instruction[31:25], instruction[11:7]}; + we_reg = 0; + adder_pc = 0; + data_out = 0; + input_reg = 2'b01; + select_a = instruction[19:15]; + select_b = instruction[24:20]; + select_d = 5'b00000; + source_alu = 0; + op_code_alu = branch_op_code(instruction[14:12]); + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 1; + alu_not = branch_not(instruction[14:12]); + end + 5'b11011 : begin // JUMP - Jal + immediate = instruction[31:12]; + we_reg = 1; + adder_pc = 0; + data_out = 0; + input_reg = 2'b00; + select_a = 5'b00000; + select_b = 5'b00000; + select_d = instruction[11:7]; + source_alu = 0; + op_code_alu = 3'b000; + mem_we = 0; + jmp_pc = 2'b01; + b_pc = 0; + alu_not = 0; + end + 5'b11001 : begin // JUMP REG - Jalr + immediate = instruction[31:20]; + we_reg = 1; + adder_pc = 0; + data_out = 0; + input_reg = 2'b00; + select_a = instruction[19:15]; + select_b = 5'b00000; + select_d = instruction[11:7]; + source_alu = 0; + op_code_alu = 3'b000; + mem_we = 0; + jmp_pc = 2'b10; + b_pc = 0; + alu_not = 0; + end + 5'b01101 : begin // LUI - lui + immediate = instruction[31:12] << 12; + we_reg = 1; + adder_pc = 0; + data_out = 1; + input_reg = 2'b01; + select_a = 5'b00000; + select_b = 5'b00000; + select_d = instruction[11:7]; + source_alu = 1; + op_code_alu = 3'b000; + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + end + 5'b00101 : begin // AUIPC - auipc + immediate = instruction[31:12] << 12; + we_reg = 1; + adder_pc = 1; + data_out = 1; + input_reg = 2'b00; + select_a = 5'b00000; + select_b = 5'b00000; + select_d = instruction[11:7]; + source_alu = 0; + op_code_alu = 3'b000; + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + end + default : begin // NOP + immediate = 32'b0; + we_reg = 0; + adder_pc = 0; + data_out = 0; + input_reg = 2'b00; + select_a = 5'b00000; + select_b = 5'b00000; + select_d = 5'b00000; + source_alu = 0; + op_code_alu = 3'b000; + mem_we = 0; + jmp_pc = 2'b00; + b_pc = 0; + alu_not = 0; + end + endcase end endmodule diff --git a/rtl/memory.v b/rtl/memory.v index a19b913..bde7231 100644 --- a/rtl/memory.v +++ b/rtl/memory.v @@ -1,7 +1,7 @@ -module instruction (input clock, reset, +module memory (input clock, reset, input we, input [31:0] address, - input [31:0] data_in + input [31:0] data_in, output [31:0] data_out); reg [63:0] memory [31:0]; diff --git a/rtl/mux2_1.v b/rtl/mux2_1.v index 3711974..267a48e 100644 --- a/rtl/mux2_1.v +++ b/rtl/mux2_1.v @@ -1,6 +1,7 @@ -module mux2_1 (input [31:0] A, B, - input S, - output [31:0] O); +module mux2_1 #(parameter BUS_SIZE = 32) + (input [BUS_SIZE - 1:0] A, B, + input S, + output [BUS_SIZE - 1:0] O); assign O = S ? B : A; diff --git a/rtl/mux4_1.v b/rtl/mux4_1.v index 80c50ab..49de354 100644 --- a/rtl/mux4_1.v +++ b/rtl/mux4_1.v @@ -1,6 +1,7 @@ -module mux4_1 (input [31:0] A, B, C, D, - input [1:0] S, - output [31:0] O); +module mux4_1 #(parameter BUS_SIZE = 32) + (input [BUS_SIZE - 1:0] A, B, C, D, + input [1:0] S, + output [BUS_SIZE - 1:0] O); assign O = S[0] ? (S[1] ? D : C) : (S[1] ? B : A); diff --git a/rtl/risc-v_cpu.v b/rtl/risc-v_cpu.v deleted file mode 100644 index e69de29..0000000 diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v new file mode 100644 index 0000000..a67059f --- /dev/null +++ b/rtl/risc_v_cpu.v @@ -0,0 +1,127 @@ +module risc_v_cpu (input clock, reset, output [31:0] out); + + wire [31:0] in_b; + wire [31:0] alu_out; + + wire [31:0] instruction; + wire we_reg, adder_pc, data_out; + wire [1:0] input_reg; + wire [4:0] select_a, select_b, select_d; + wire source_alu; + wire [3:0] op_code_alu; + wire mem_we; + wire [1:0] jmp_pc; + wire b_pc, alu_not; + + wire [31:0] input_d; + wire [31:0] output_a, output_b; + + wire [31:0] immediate; + + wire [31:0] pc; + wire [31:0] new_pc; + + wire [1:0] pc_in; + + wire [31:0] memory_out; + + wire [31:0] pc_store; + + decoder decoder ( + .instruction(instruction), + .immediate(immediate), + .we_reg(we_reg), + .adder_pc(adder_pc), + .data_out(data_out), + .input_reg(input_reg), + .select_a(select_a), + .select_b(select_b), + .select_d(select_d), + .source_alu(source_alu), + .op_code_alu(op_code_alu), + .mem_we(mem_we), + .jmp_pc(jmp_pc), + .b_pc(b_pc), + .alu_not(alu_not) + ); + + registers_bank registers_bank ( + .clock(clock), + .reset(reset), + .we(we_reg), + .select_d(select_d), + .select_a(select_a), + .select_b(select_b), + .input_d(input_d), + .output_a(output_a), + .output_b(output_b) + ); + + mux2_1 mux2_1_1 ( + .A(output_b), + .B(immediate), + .S(source_alu), + .O(in_b) + ); + + alu alu ( + .input_a(output_a), + .input_b(in_b), + .op_code(op_code_alu), + .out(alu_out) + ); + + mux2_1 #(2) mux2_1_2 ( + .A(jmp_pc), + .B({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}), + .S(b_pc), + .O(pc_in) + ); + + mux4_1 mux4_1_1 ( + .A(pc + 4), + .B(pc + immediate), + .C(alu_out), + .D(0), + .S(pc_in), + .O(new_pc) + ); + + program_counter program_counter ( + .clock(clock), + .reset(clock), + .new_pc(new_pc), + .pc(pc) + ); + + instruction uut_instruction ( + .address(pc), + .instruction(instruction) + ); + + memory memory ( + .clock(clock), + .reset(reset), + .we(mem_we), + .address(alu_out), + .data_in(output_b), + .data_out(memory_out) + ); + + mux2_1 mux2_1_3 ( + .A(4), + .B(alu_out), + .S(adder_pc), + .O(pc_store) + ); + + mux4_1 mux4_1_2 ( + .A(pc_store + pc), + .B(alu_out), + .C(memory_out), + .D(0), + .S(input_reg), + .O(input_d) + ); + +endmodule diff --git a/tb/tb_risc-v_cpu.v b/tb/tb_risc-v_cpu.v deleted file mode 100644 index e69de29..0000000 diff --git a/tb/tb_risc_v_cpu.v b/tb/tb_risc_v_cpu.v new file mode 100644 index 0000000..b5c5139 --- /dev/null +++ b/tb/tb_risc_v_cpu.v @@ -0,0 +1,31 @@ +`timescale 1ns / 1ps + +module tb_risc_v_cpu (); +// Clock and reset signals +reg clk; +reg reset; + +// Design Inputs and outputs +wire [31:0] out; + +// DUT instantiation +risc_v_cpu risc_v_cpu ( + .clock(clk), + .reset(reset), + .out(out) +); + +// generate the clock +initial begin + clk = 1'b0; + forever #1 clk = ~clk; +end + +// Generate the reset +initial begin + reset = 1'b1; + #10 + reset = 1'b0; +end + +endmodule : tb_risc_v_cpu -- 2.30.2 From 33835ec0ed7674d3022fdb1bf7ee3c56a7803de7 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Sun, 22 Oct 2023 22:41:39 +0900 Subject: [PATCH 03/17] Fix: reset edge --- rtl/instruction.v | 43 ++++++++++++++++++++++++++++++++++++++++++- rtl/memory.v | 2 +- rtl/mux4_1.v | 4 ++-- rtl/program_counter.v | 4 ++-- rtl/registers_bank.v | 25 ++++++++++++++++++++++++- rtl/risc_v_cpu.v | 2 +- tb/tb_risc_v_cpu.v | 17 +++++++++++------ 7 files changed, 83 insertions(+), 14 deletions(-) diff --git a/rtl/instruction.v b/rtl/instruction.v index a91d9fb..fd3d125 100644 --- a/rtl/instruction.v +++ b/rtl/instruction.v @@ -1,8 +1,49 @@ module instruction (input [31:0] address, output [31:0] instruction); - reg [63:0] memory [31:0]; + reg [31:0] memory [63:0]; + + // ADDi $1, R[0], R[6] + // "000000000001_00000_000_00110_0010000" + assign memory[0] = 32'b00000000000100000000001100010000; + + // ADDi $0, R[0], R[7] + // "000000000000_00000_000_00111_0010000" + assign memory[4] = 32'b00000000000000000000001110010000; + + // ADDi $0, R[6], R[8] + // "000000000000_00110_000_01000_0010000" + assign memory[8] = 32'b00000000000000110000010000010000; + + // ADD R[7], R[6], R[6] + // "0000000_00111_00110_000_00110_0110000" + assign memory[12] = 32'b00000000011100110000001100110000; + + // ADDi $0, R[8], R[7] + // "000000000000_01000_000_00111_0010000" + assign memory[16] = 32'b00000000000001000000001110010000; + + // JUMP + // 111111111111_11111_101_00111_1101100 + assign memory[20] = 32'b11111111111111111101001111101100; assign instruction = memory[address]; endmodule + +// -- result(1) := "00000000001100110000010000010000"; + +// -- "000000000000_00000_000_00110_0010000" +// result(0) := "00000000000100000000001100010000"; +// -- "000000000001_00000_000_00111_0010000" +// result(1) := "00000000000000000000001110010000"; + +// -- "000000000000_00110_000_01000_0010000" +// result(2) := "00000000000000110000010000010000"; +// -- "0000000_00111_00110_000_00110_0110000" +// result(3) := "00000000011100110000001100110000"; +// -- "000000000000_01000_000_00111_0010000" +// result(4) := "00000000000001000000001110010000"; + +// -- 111111111111_11111_110_00111_1101100 +// result(5) := "11111111111111111101001111101100"; \ No newline at end of file diff --git a/rtl/memory.v b/rtl/memory.v index bde7231..0c6f8e7 100644 --- a/rtl/memory.v +++ b/rtl/memory.v @@ -6,7 +6,7 @@ module memory (input clock, reset, reg [63:0] memory [31:0]; - always @(posedge clock, reset) begin + always @(posedge clock, posedge reset) begin if (reset == 1) memory[0] <= 32'b0; else if (we == 1) diff --git a/rtl/mux4_1.v b/rtl/mux4_1.v index 49de354..8c6b3c0 100644 --- a/rtl/mux4_1.v +++ b/rtl/mux4_1.v @@ -3,7 +3,7 @@ module mux4_1 #(parameter BUS_SIZE = 32) input [1:0] S, output [BUS_SIZE - 1:0] O); - assign O = S[0] ? (S[1] ? D : C) - : (S[1] ? B : A); + assign O = S[1] ? (S[0] ? D : C) + : (S[0] ? B : A); endmodule diff --git a/rtl/program_counter.v b/rtl/program_counter.v index c9dfc65..966e06c 100644 --- a/rtl/program_counter.v +++ b/rtl/program_counter.v @@ -2,8 +2,8 @@ module program_counter (input clock, reset, input [31:0] new_pc, output reg [31:0] pc); - always @ (posedge clock, reset) begin - if (reset == 1) + always @ (posedge clock, posedge reset) begin + if (reset == 1'b1) pc <= 32'b0; else pc <= new_pc; diff --git a/rtl/registers_bank.v b/rtl/registers_bank.v index 3af16b2..db46e3e 100644 --- a/rtl/registers_bank.v +++ b/rtl/registers_bank.v @@ -4,8 +4,31 @@ module registers_bank (input clock, reset, we, output [31:0] output_a, output_b); reg [31:0] registers[31:0]; + + assign registers[0] = 32'b0; + assign registers[1] = 32'b0; + assign registers[2] = 32'b0; + assign registers[3] = 32'b0; + assign registers[4] = 32'b0; + assign registers[5] = 32'b0; + assign registers[6] = 32'b0; + assign registers[7] = 32'b0; + assign registers[8] = 32'b0; + assign registers[9] = 32'b0; + assign registers[10] = 32'b0; + assign registers[11] = 32'b0; + assign registers[12] = 32'b0; + assign registers[13] = 32'b0; + assign registers[14] = 32'b0; + assign registers[15] = 32'b0; + assign registers[16] = 32'b0; + assign registers[17] = 32'b0; + assign registers[18] = 32'b0; + assign registers[19] = 32'b0; + assign registers[20] = 32'b0; + assign registers[21] = 32'b0; - always @(posedge clock, reset) begin + always @(posedge clock, posedge reset) begin if (reset == 1) registers[0] <= 32'b0; else if (we == 1) diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index a67059f..bdf5f76 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -89,7 +89,7 @@ module risc_v_cpu (input clock, reset, output [31:0] out); program_counter program_counter ( .clock(clock), - .reset(clock), + .reset(reset), .new_pc(new_pc), .pc(pc) ); diff --git a/tb/tb_risc_v_cpu.v b/tb/tb_risc_v_cpu.v index b5c5139..41852e0 100644 --- a/tb/tb_risc_v_cpu.v +++ b/tb/tb_risc_v_cpu.v @@ -1,6 +1,8 @@ `timescale 1ns / 1ps module tb_risc_v_cpu (); +integer i; + // Clock and reset signals reg clk; reg reset; @@ -15,12 +17,6 @@ risc_v_cpu risc_v_cpu ( .out(out) ); -// generate the clock -initial begin - clk = 1'b0; - forever #1 clk = ~clk; -end - // Generate the reset initial begin reset = 1'b1; @@ -28,4 +24,13 @@ initial begin reset = 1'b0; end + +// generate the clock +initial begin + clk = 1'b0; + for (i = 0; i < 100; i = i + 1) begin + #1 clk = ~clk; + end +end + endmodule : tb_risc_v_cpu -- 2.30.2 From 766f77fa6c62961f0f6838a5ba827daeae65ec87 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 09:41:40 +0900 Subject: [PATCH 04/17] Add: sign extension - cpu is now able to compute fibonacci --- rtl/decoder.v | 28 +++++++++++++++++----------- rtl/instruction.v | 14 +++++++------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/rtl/decoder.v b/rtl/decoder.v index 9312975..dba0a96 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -12,12 +12,12 @@ module decoder (input [31:0] instruction, function [3:0] get_op_code_alu(input [2:0] op_code, input arithmetic); begin case (op_code) - 3'b000 : get_op_code_alu = arithmetic ? 4'b0000 : 4'b0001; + 3'b000 : get_op_code_alu = arithmetic ? 4'b0001 : 4'b0000; 3'b001 : get_op_code_alu = 4'b0010; 3'b010 : get_op_code_alu = 4'b0011; 3'b011 : get_op_code_alu = 4'b0011; 3'b100 : get_op_code_alu = 4'b0100; - 3'b101 : get_op_code_alu = arithmetic ? 4'b0101 : 4'b0111; + 3'b101 : get_op_code_alu = arithmetic ? 4'b0111 : 4'b0101; 3'b110 : get_op_code_alu = 4'b1000; 3'b111 : get_op_code_alu = 4'b1010; 3'b111 : get_op_code_alu = 4'b1011; @@ -34,7 +34,7 @@ function [3:0] get_op_code_alu_imm(input [2:0] op_code, input arithmetic); 3'b010 : get_op_code_alu_imm = 4'b0011; 3'b011 : get_op_code_alu_imm = 4'b0100; 3'b100 : get_op_code_alu_imm = 4'b0101; - 3'b101 : get_op_code_alu_imm = arithmetic ? 4'b0111 : 4'b1000; + 3'b101 : get_op_code_alu_imm = arithmetic ? 4'b1000 : 4'b0111; 3'b110 : get_op_code_alu_imm = 4'b1001; 3'b111 : get_op_code_alu_imm = 4'b1010; 3'b111 : get_op_code_alu_imm = 4'b1011; @@ -94,7 +94,8 @@ endfunction alu_not = 0; end 5'b00100 : begin // OP-IMM - Addi, ... - immediate = instruction[31:20]; + immediate[11:0] = instruction[31:20]; + immediate[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; adder_pc = 0; data_out = 0; @@ -110,7 +111,8 @@ endfunction alu_not = 0; end 5'b00000 : begin // LOAD - Lw, ... - immediate = instruction[31:20]; + immediate[11:0] = instruction[31:20]; + immediate[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; adder_pc = 0; data_out = 0; @@ -126,7 +128,8 @@ endfunction alu_not = 0; end 5'b01000 : begin // STORE - Sw, ... - immediate = {instruction[31:25], instruction[11:7]}; + immediate[11:0] = {instruction[31:25], instruction[11:7]}; + immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 0; adder_pc = 0; data_out = 0; @@ -142,7 +145,8 @@ endfunction alu_not = 0; end 5'b11000 : begin // BRANCH - Beq, ... - immediate = {instruction[31:25], instruction[11:7]}; + immediate[11:0] = {instruction[31:25], instruction[11:7]}; + immediate[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 0; adder_pc = 0; data_out = 0; @@ -158,7 +162,8 @@ endfunction alu_not = branch_not(instruction[14:12]); end 5'b11011 : begin // JUMP - Jal - immediate = instruction[31:12]; + immediate[19:0] = instruction[31:12]; + immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; we_reg = 1; adder_pc = 0; data_out = 0; @@ -174,7 +179,8 @@ endfunction alu_not = 0; end 5'b11001 : begin // JUMP REG - Jalr - immediate = instruction[31:20]; + immediate[19:0] = instruction[31:12]; + immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; we_reg = 1; adder_pc = 0; data_out = 0; @@ -190,7 +196,7 @@ endfunction alu_not = 0; end 5'b01101 : begin // LUI - lui - immediate = instruction[31:12] << 12; + immediate = {instruction[31:12] << 12, 12'b000000000000}; we_reg = 1; adder_pc = 0; data_out = 1; @@ -206,7 +212,7 @@ endfunction alu_not = 0; end 5'b00101 : begin // AUIPC - auipc - immediate = instruction[31:12] << 12; + immediate = {instruction[31:12] << 12, 12'b000000000000}; we_reg = 1; adder_pc = 1; data_out = 1; diff --git a/rtl/instruction.v b/rtl/instruction.v index fd3d125..8ac4e87 100644 --- a/rtl/instruction.v +++ b/rtl/instruction.v @@ -3,29 +3,29 @@ module instruction (input [31:0] address, reg [31:0] memory [63:0]; - // ADDi $1, R[0], R[6] + // ADDi $1, R[0], R[6] - R[6] = 1 // "000000000001_00000_000_00110_0010000" assign memory[0] = 32'b00000000000100000000001100010000; - // ADDi $0, R[0], R[7] + // ADDi $0, R[0], R[7] - R[7] = 0 // "000000000000_00000_000_00111_0010000" assign memory[4] = 32'b00000000000000000000001110010000; - // ADDi $0, R[6], R[8] + // ADDi $0, R[6], R[8] - R[8] = R[6] // "000000000000_00110_000_01000_0010000" assign memory[8] = 32'b00000000000000110000010000010000; - // ADD R[7], R[6], R[6] + // ADD R[7], R[6], R[6] - R[6] = R[7] + R[6] // "0000000_00111_00110_000_00110_0110000" assign memory[12] = 32'b00000000011100110000001100110000; - // ADDi $0, R[8], R[7] + // ADDi $0, R[8], R[7] - R[7] = R[8] // "000000000000_01000_000_00111_0010000" assign memory[16] = 32'b00000000000001000000001110010000; // JUMP - // 111111111111_11111_101_00111_1101100 - assign memory[20] = 32'b11111111111111111101001111101100; + // 11111111111111111101_00111_1101100 + assign memory[20] = 32'b11111111111111110100001011101100; assign instruction = memory[address]; -- 2.30.2 From 54e3ecdfa35052b58c23751edfc9bbd2a0a5b10c Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 09:50:51 +0900 Subject: [PATCH 05/17] Fix: set right value alu auipc --- rtl/decoder.v | 15 ++------------- rtl/risc_v_cpu.v | 3 +-- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/rtl/decoder.v b/rtl/decoder.v index dba0a96..dc517e3 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -1,6 +1,6 @@ module decoder (input [31:0] instruction, output reg [31:0] immediate, - output reg we_reg, adder_pc, data_out, + output reg we_reg, adder_pc, output reg [1:0] input_reg, output reg [4:0] select_a, select_b, select_d, output reg source_alu, @@ -80,7 +80,6 @@ endfunction immediate = 0; we_reg = 1; adder_pc = 0; - data_out = 0; input_reg = 2'b01; select_a = instruction[19:15]; select_b = instruction[24:20]; @@ -91,14 +90,12 @@ endfunction jmp_pc = 2'b00; b_pc = 0; alu_not = 0; - alu_not = 0; end 5'b00100 : begin // OP-IMM - Addi, ... immediate[11:0] = instruction[31:20]; immediate[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; adder_pc = 0; - data_out = 0; input_reg = 2'b01; select_a = instruction[19:15]; select_b = 5'b00000; @@ -115,7 +112,6 @@ endfunction immediate[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; adder_pc = 0; - data_out = 0; input_reg = 2'b10; select_a = instruction[19:15]; select_b = 5'b00000; @@ -132,7 +128,6 @@ endfunction immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 0; adder_pc = 0; - data_out = 0; input_reg = 2'b01; select_a = instruction[19:15]; select_b = instruction[24:20]; @@ -149,7 +144,6 @@ endfunction immediate[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 0; adder_pc = 0; - data_out = 0; input_reg = 2'b01; select_a = instruction[19:15]; select_b = instruction[24:20]; @@ -166,7 +160,6 @@ endfunction immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; we_reg = 1; adder_pc = 0; - data_out = 0; input_reg = 2'b00; select_a = 5'b00000; select_b = 5'b00000; @@ -183,7 +176,6 @@ endfunction immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; we_reg = 1; adder_pc = 0; - data_out = 0; input_reg = 2'b00; select_a = instruction[19:15]; select_b = 5'b00000; @@ -199,7 +191,6 @@ endfunction immediate = {instruction[31:12] << 12, 12'b000000000000}; we_reg = 1; adder_pc = 0; - data_out = 1; input_reg = 2'b01; select_a = 5'b00000; select_b = 5'b00000; @@ -215,12 +206,11 @@ endfunction immediate = {instruction[31:12] << 12, 12'b000000000000}; we_reg = 1; adder_pc = 1; - data_out = 1; input_reg = 2'b00; select_a = 5'b00000; select_b = 5'b00000; select_d = instruction[11:7]; - source_alu = 0; + source_alu = 1; op_code_alu = 3'b000; mem_we = 0; jmp_pc = 2'b00; @@ -231,7 +221,6 @@ endfunction immediate = 32'b0; we_reg = 0; adder_pc = 0; - data_out = 0; input_reg = 2'b00; select_a = 5'b00000; select_b = 5'b00000; diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index bdf5f76..fe8428c 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -4,7 +4,7 @@ module risc_v_cpu (input clock, reset, output [31:0] out); wire [31:0] alu_out; wire [31:0] instruction; - wire we_reg, adder_pc, data_out; + wire we_reg, adder_pc; wire [1:0] input_reg; wire [4:0] select_a, select_b, select_d; wire source_alu; @@ -32,7 +32,6 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .immediate(immediate), .we_reg(we_reg), .adder_pc(adder_pc), - .data_out(data_out), .input_reg(input_reg), .select_a(select_a), .select_b(select_b), -- 2.30.2 From 57216f7c85e9f53ec644710b1ca54a96ace72d9e Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 10:10:49 +0900 Subject: [PATCH 06/17] Fix: use parameter to name op code --- rtl/decoder.v | 24 +++++++++++++----------- rtl/op_code.vh | 9 +++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 rtl/op_code.vh diff --git a/rtl/decoder.v b/rtl/decoder.v index dc517e3..a6f30de 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -9,6 +9,8 @@ module decoder (input [31:0] instruction, output reg [1:0] jmp_pc, output reg b_pc, alu_not); +`include "op_code.vh" + function [3:0] get_op_code_alu(input [2:0] op_code, input arithmetic); begin case (op_code) @@ -76,7 +78,7 @@ endfunction always @(*) begin case (instruction[6:2]) - 5'b01100 : begin // OP - Add, ... + OP : begin // OP - Add, ... immediate = 0; we_reg = 1; adder_pc = 0; @@ -91,7 +93,7 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b00100 : begin // OP-IMM - Addi, ... + OP_IMM : begin // OP-IMM - Addi, ... immediate[11:0] = instruction[31:20]; immediate[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; @@ -107,7 +109,7 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b00000 : begin // LOAD - Lw, ... + LOAD : begin // LOAD - Lw, ... immediate[11:0] = instruction[31:20]; immediate[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; @@ -123,7 +125,7 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b01000 : begin // STORE - Sw, ... + STORE : begin // STORE - Sw, ... immediate[11:0] = {instruction[31:25], instruction[11:7]}; immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 0; @@ -139,7 +141,7 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b11000 : begin // BRANCH - Beq, ... + BRANCH : begin // BRANCH - Beq, ... immediate[11:0] = {instruction[31:25], instruction[11:7]}; immediate[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 0; @@ -155,7 +157,7 @@ endfunction b_pc = 1; alu_not = branch_not(instruction[14:12]); end - 5'b11011 : begin // JUMP - Jal + JAL : begin // JUMP - Jal immediate[19:0] = instruction[31:12]; immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; we_reg = 1; @@ -171,9 +173,9 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b11001 : begin // JUMP REG - Jalr - immediate[19:0] = instruction[31:12]; - immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; + JALR : begin // JUMP REG - Jalr + immediate[11:0] = instruction[31:20]; + immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; we_reg = 1; adder_pc = 0; input_reg = 2'b00; @@ -187,7 +189,7 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b01101 : begin // LUI - lui + LUI : begin // LUI - lui immediate = {instruction[31:12] << 12, 12'b000000000000}; we_reg = 1; adder_pc = 0; @@ -202,7 +204,7 @@ endfunction b_pc = 0; alu_not = 0; end - 5'b00101 : begin // AUIPC - auipc + AUIPC : begin // AUIPC - auipc immediate = {instruction[31:12] << 12, 12'b000000000000}; we_reg = 1; adder_pc = 1; diff --git a/rtl/op_code.vh b/rtl/op_code.vh new file mode 100644 index 0000000..437441a --- /dev/null +++ b/rtl/op_code.vh @@ -0,0 +1,9 @@ +parameter [4:0] OP = 5'b01100; +parameter [4:0] OP_IMM = 5'b00100; +parameter [4:0] LOAD = 5'b00000; +parameter [4:0] STORE = 5'b01000; +parameter [4:0] BRANCH = 5'b11000; +parameter [4:0] JAL = 5'b11011; +parameter [4:0] JALR = 5'b11001; +parameter [4:0] LUI = 5'b01101; +parameter [4:0] AUIPC = 5'b00101; -- 2.30.2 From 44ac59210cc7cf7a417a303ec40783523375e81b Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 11:24:09 +0900 Subject: [PATCH 07/17] Fix: clean name [1] --- rtl/decoder.v | 228 +++++++++++++++++++++--------------------- rtl/program_counter.v | 8 +- rtl/registers_bank.v | 10 +- rtl/risc_v_cpu.v | 96 +++++++++--------- 4 files changed, 169 insertions(+), 173 deletions(-) diff --git a/rtl/decoder.v b/rtl/decoder.v index a6f30de..b254ac0 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -1,46 +1,46 @@ module decoder (input [31:0] instruction, - output reg [31:0] immediate, - output reg we_reg, adder_pc, - output reg [1:0] input_reg, - output reg [4:0] select_a, select_b, select_d, - output reg source_alu, - output reg [3:0] op_code_alu, + output reg [31:0] imm, + output reg reg_we, adder_pc, + output reg [1:0] reg_sel_data_in, + output reg [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in, + output reg alu_src, + output reg [3:0] alu_func, output reg mem_we, output reg [1:0] jmp_pc, output reg b_pc, alu_not); `include "op_code.vh" -function [3:0] get_op_code_alu(input [2:0] op_code, input arithmetic); +function [3:0] get_alu_func(input [2:0] op_code, input arithmetic); begin case (op_code) - 3'b000 : get_op_code_alu = arithmetic ? 4'b0001 : 4'b0000; - 3'b001 : get_op_code_alu = 4'b0010; - 3'b010 : get_op_code_alu = 4'b0011; - 3'b011 : get_op_code_alu = 4'b0011; - 3'b100 : get_op_code_alu = 4'b0100; - 3'b101 : get_op_code_alu = arithmetic ? 4'b0111 : 4'b0101; - 3'b110 : get_op_code_alu = 4'b1000; - 3'b111 : get_op_code_alu = 4'b1010; - 3'b111 : get_op_code_alu = 4'b1011; - default : get_op_code_alu= 4'b0000; + 3'b000 : get_alu_func = arithmetic ? 4'b0001 : 4'b0000; + 3'b001 : get_alu_func = 4'b0010; + 3'b010 : get_alu_func = 4'b0011; + 3'b011 : get_alu_func = 4'b0011; + 3'b100 : get_alu_func = 4'b0100; + 3'b101 : get_alu_func = arithmetic ? 4'b0111 : 4'b0101; + 3'b110 : get_alu_func = 4'b1000; + 3'b111 : get_alu_func = 4'b1010; + 3'b111 : get_alu_func = 4'b1011; + default : get_alu_func= 4'b0000; endcase end endfunction -function [3:0] get_op_code_alu_imm(input [2:0] op_code, input arithmetic); +function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic); begin case (op_code) - 3'b000 : get_op_code_alu_imm = 4'b0000; - 3'b001 : get_op_code_alu_imm = 4'b0010; - 3'b010 : get_op_code_alu_imm = 4'b0011; - 3'b011 : get_op_code_alu_imm = 4'b0100; - 3'b100 : get_op_code_alu_imm = 4'b0101; - 3'b101 : get_op_code_alu_imm = arithmetic ? 4'b1000 : 4'b0111; - 3'b110 : get_op_code_alu_imm = 4'b1001; - 3'b111 : get_op_code_alu_imm = 4'b1010; - 3'b111 : get_op_code_alu_imm = 4'b1011; - default : get_op_code_alu_imm = 4'b0000; + 3'b000 : get_alu_func_imm = 4'b0000; + 3'b001 : get_alu_func_imm = 4'b0010; + 3'b010 : get_alu_func_imm = 4'b0011; + 3'b011 : get_alu_func_imm = 4'b0100; + 3'b100 : get_alu_func_imm = 4'b0101; + 3'b101 : get_alu_func_imm = arithmetic ? 4'b1000 : 4'b0111; + 3'b110 : get_alu_func_imm = 4'b1001; + 3'b111 : get_alu_func_imm = 4'b1010; + 3'b111 : get_alu_func_imm = 4'b1011; + default : get_alu_func_imm = 4'b0000; endcase end endfunction @@ -79,156 +79,156 @@ endfunction always @(*) begin case (instruction[6:2]) OP : begin // OP - Add, ... - immediate = 0; - we_reg = 1; + imm = 0; + reg_we = 1; adder_pc = 0; - input_reg = 2'b01; - select_a = instruction[19:15]; - select_b = instruction[24:20]; - select_d = instruction[11:7]; - source_alu = 0; - op_code_alu = get_op_code_alu(instruction[14:12], instruction[30]); + reg_sel_data_in = 2'b00; + reg_sel_out_a = instruction[19:15]; + reg_sel_out_b = instruction[24:20]; + reg_sel_in = instruction[11:7]; + alu_src = 0; + alu_func = get_alu_func(instruction[14:12], instruction[30]); mem_we = 0; jmp_pc = 2'b00; b_pc = 0; alu_not = 0; end OP_IMM : begin // OP-IMM - Addi, ... - immediate[11:0] = instruction[31:20]; - immediate[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; - we_reg = 1; + imm[11:0] = instruction[31:20]; + imm[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; + reg_we = 1; adder_pc = 0; - input_reg = 2'b01; - select_a = instruction[19:15]; - select_b = 5'b00000; - select_d = instruction[11:7]; - source_alu = 1; - op_code_alu = get_op_code_alu_imm(instruction[14:12], instruction[30]); + reg_sel_data_in = 2'b00; + reg_sel_out_a = instruction[19:15]; + reg_sel_out_b = 5'b00000; + reg_sel_in = instruction[11:7]; + alu_src = 1; + alu_func = get_alu_func_imm(instruction[14:12], instruction[30]); mem_we = 0; jmp_pc = 2'b00; b_pc = 0; alu_not = 0; end LOAD : begin // LOAD - Lw, ... - immediate[11:0] = instruction[31:20]; - immediate[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; - we_reg = 1; + imm[11:0] = instruction[31:20]; + imm[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; + reg_we = 1; adder_pc = 0; - input_reg = 2'b10; - select_a = instruction[19:15]; - select_b = 5'b00000; - select_d = instruction[11:7]; - source_alu = 1; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b01; + reg_sel_out_a = instruction[19:15]; + reg_sel_out_b = 5'b00000; + reg_sel_in = instruction[11:7]; + alu_src = 1; + alu_func = 3'b000; mem_we = 0; jmp_pc = 2'b00; b_pc = 0; alu_not = 0; end STORE : begin // STORE - Sw, ... - immediate[11:0] = {instruction[31:25], instruction[11:7]}; - immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; - we_reg = 0; + imm[11:0] = {instruction[31:25], instruction[11:7]}; + imm[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; + reg_we = 0; adder_pc = 0; - input_reg = 2'b01; - select_a = instruction[19:15]; - select_b = instruction[24:20]; - select_d = 5'b00000; - source_alu = 1; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b00; + reg_sel_out_a = instruction[19:15]; + reg_sel_out_b = instruction[24:20]; + reg_sel_in = 5'b00000; + alu_src = 1; + alu_func = 3'b000; mem_we = 1; jmp_pc = 2'b00; b_pc = 0; alu_not = 0; end BRANCH : begin // BRANCH - Beq, ... - immediate[11:0] = {instruction[31:25], instruction[11:7]}; - immediate[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; - we_reg = 0; + imm[11:0] = {instruction[31:25], instruction[11:7]}; + imm[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; + reg_we = 0; adder_pc = 0; - input_reg = 2'b01; - select_a = instruction[19:15]; - select_b = instruction[24:20]; - select_d = 5'b00000; - source_alu = 0; - op_code_alu = branch_op_code(instruction[14:12]); + reg_sel_data_in = 2'b00; + reg_sel_out_a = instruction[19:15]; + reg_sel_out_b = instruction[24:20]; + reg_sel_in = 5'b00000; + alu_src = 0; + alu_func = branch_op_code(instruction[14:12]); mem_we = 0; jmp_pc = 2'b00; b_pc = 1; alu_not = branch_not(instruction[14:12]); end JAL : begin // JUMP - Jal - immediate[19:0] = instruction[31:12]; - immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; - we_reg = 1; + imm[19:0] = instruction[31:12]; + imm[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; + reg_we = 1; adder_pc = 0; - input_reg = 2'b00; - select_a = 5'b00000; - select_b = 5'b00000; - select_d = instruction[11:7]; - source_alu = 0; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b10; + reg_sel_out_a = 5'b00000; + reg_sel_out_b = 5'b00000; + reg_sel_in = instruction[11:7]; + alu_src = 0; + alu_func = 3'b000; mem_we = 0; jmp_pc = 2'b01; b_pc = 0; alu_not = 0; end JALR : begin // JUMP REG - Jalr - immediate[11:0] = instruction[31:20]; - immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; - we_reg = 1; + imm[11:0] = instruction[31:20]; + imm[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; + reg_we = 1; adder_pc = 0; - input_reg = 2'b00; - select_a = instruction[19:15]; - select_b = 5'b00000; - select_d = instruction[11:7]; - source_alu = 0; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b10; + reg_sel_out_a = instruction[19:15]; + reg_sel_out_b = 5'b00000; + reg_sel_in = instruction[11:7]; + alu_src = 0; + alu_func = 3'b000; mem_we = 0; jmp_pc = 2'b10; b_pc = 0; alu_not = 0; end LUI : begin // LUI - lui - immediate = {instruction[31:12] << 12, 12'b000000000000}; - we_reg = 1; + imm = {instruction[31:12] << 12, 12'b000000000000}; + reg_we = 1; adder_pc = 0; - input_reg = 2'b01; - select_a = 5'b00000; - select_b = 5'b00000; - select_d = instruction[11:7]; - source_alu = 1; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b00; + reg_sel_out_a = 5'b00000; + reg_sel_out_b = 5'b00000; + reg_sel_in = instruction[11:7]; + alu_src = 1; + alu_func = 3'b000; mem_we = 0; jmp_pc = 2'b00; b_pc = 0; alu_not = 0; end AUIPC : begin // AUIPC - auipc - immediate = {instruction[31:12] << 12, 12'b000000000000}; - we_reg = 1; + imm = {instruction[31:12] << 12, 12'b000000000000}; + reg_we = 1; adder_pc = 1; - input_reg = 2'b00; - select_a = 5'b00000; - select_b = 5'b00000; - select_d = instruction[11:7]; - source_alu = 1; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b11; + reg_sel_out_a = 5'b00000; + reg_sel_out_b = 5'b00000; + reg_sel_in = instruction[11:7]; + alu_src = 1; + alu_func = 3'b000; mem_we = 0; jmp_pc = 2'b00; b_pc = 0; alu_not = 0; end default : begin // NOP - immediate = 32'b0; - we_reg = 0; + imm = 32'b0; + reg_we = 0; adder_pc = 0; - input_reg = 2'b00; - select_a = 5'b00000; - select_b = 5'b00000; - select_d = 5'b00000; - source_alu = 0; - op_code_alu = 3'b000; + reg_sel_data_in = 2'b00; + reg_sel_out_a = 5'b00000; + reg_sel_out_b = 5'b00000; + reg_sel_in = 5'b00000; + alu_src = 0; + alu_func = 3'b000; mem_we = 0; jmp_pc = 2'b00; b_pc = 0; diff --git a/rtl/program_counter.v b/rtl/program_counter.v index 966e06c..8345db8 100644 --- a/rtl/program_counter.v +++ b/rtl/program_counter.v @@ -1,12 +1,12 @@ module program_counter (input clock, reset, - input [31:0] new_pc, - output reg [31:0] pc); + input [31:0] pc_new_addr, + output reg [31:0] pc_addr); always @ (posedge clock, posedge reset) begin if (reset == 1'b1) - pc <= 32'b0; + pc_addr <= 32'b0; else - pc <= new_pc; + pc_addr <= pc_new_addr; end endmodule diff --git a/rtl/registers_bank.v b/rtl/registers_bank.v index db46e3e..e60ba2e 100644 --- a/rtl/registers_bank.v +++ b/rtl/registers_bank.v @@ -1,6 +1,6 @@ module registers_bank (input clock, reset, we, - input [4:0] select_d, select_a, select_b, - input [31:0] input_d, + input [4:0] sel_in, sel_out_a, sel_out_b, + input [31:0] data_in, output [31:0] output_a, output_b); reg [31:0] registers[31:0]; @@ -32,10 +32,10 @@ module registers_bank (input clock, reset, we, if (reset == 1) registers[0] <= 32'b0; else if (we == 1) - registers[select_d] <= input_d; + registers[sel_in] <= data_in; end - assign output_a = registers[select_a]; - assign output_b = registers[select_b]; + assign output_a = registers[sel_out_a]; + assign output_b = registers[sel_out_b]; endmodule diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index fe8428c..e5b3ea7 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -1,25 +1,28 @@ module risc_v_cpu (input clock, reset, output [31:0] out); - wire [31:0] in_b; + wire [31:0] alu_in_b; wire [31:0] alu_out; + wire alu_src, alu_not; + wire [3:0] alu_func; + + wire reg_we, adder_pc; + wire [1:0] reg_sel_data_in; + wire [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in; wire [31:0] instruction; - wire we_reg, adder_pc; - wire [1:0] input_reg; - wire [4:0] select_a, select_b, select_d; - wire source_alu; - wire [3:0] op_code_alu; - wire mem_we; - wire [1:0] jmp_pc; - wire b_pc, alu_not; - wire [31:0] input_d; + wire mem_we; + + wire [1:0] jmp_pc; + wire b_pc; + + wire [31:0] reg_data_in; wire [31:0] output_a, output_b; - wire [31:0] immediate; + wire [31:0] imm; - wire [31:0] pc; - wire [31:0] new_pc; + wire [31:0] pc_addr; + wire [31:0] pc_new_addr; wire [1:0] pc_in; @@ -29,15 +32,15 @@ module risc_v_cpu (input clock, reset, output [31:0] out); decoder decoder ( .instruction(instruction), - .immediate(immediate), - .we_reg(we_reg), + .imm(imm), + .reg_we(reg_we), .adder_pc(adder_pc), - .input_reg(input_reg), - .select_a(select_a), - .select_b(select_b), - .select_d(select_d), - .source_alu(source_alu), - .op_code_alu(op_code_alu), + .reg_sel_data_in(reg_sel_data_in), + .reg_sel_out_a(reg_sel_out_a), + .reg_sel_out_b(reg_sel_out_b), + .reg_sel_in(reg_sel_in), + .alu_src(alu_src), + .alu_func(alu_func), .mem_we(mem_we), .jmp_pc(jmp_pc), .b_pc(b_pc), @@ -47,26 +50,26 @@ module risc_v_cpu (input clock, reset, output [31:0] out); registers_bank registers_bank ( .clock(clock), .reset(reset), - .we(we_reg), - .select_d(select_d), - .select_a(select_a), - .select_b(select_b), - .input_d(input_d), + .we(reg_we), + .sel_in(reg_sel_in), + .sel_out_a(reg_sel_out_a), + .sel_out_b(reg_sel_out_b), + .data_in(reg_data_in), .output_a(output_a), .output_b(output_b) ); mux2_1 mux2_1_1 ( .A(output_b), - .B(immediate), - .S(source_alu), - .O(in_b) + .B(imm), + .S(alu_src), + .O(alu_in_b) ); alu alu ( .input_a(output_a), - .input_b(in_b), - .op_code(op_code_alu), + .input_b(alu_in_b), + .op_code(alu_func), .out(alu_out) ); @@ -78,23 +81,23 @@ module risc_v_cpu (input clock, reset, output [31:0] out); ); mux4_1 mux4_1_1 ( - .A(pc + 4), - .B(pc + immediate), + .A(pc_addr + 4), + .B(pc_addr + imm), .C(alu_out), .D(0), .S(pc_in), - .O(new_pc) + .O(pc_new_addr) ); program_counter program_counter ( .clock(clock), .reset(reset), - .new_pc(new_pc), - .pc(pc) + .pc_new_addr(pc_new_addr), + .pc_addr(pc_addr) ); instruction uut_instruction ( - .address(pc), + .address(pc_addr), .instruction(instruction) ); @@ -107,20 +110,13 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .data_out(memory_out) ); - mux2_1 mux2_1_3 ( - .A(4), - .B(alu_out), - .S(adder_pc), - .O(pc_store) - ); - mux4_1 mux4_1_2 ( - .A(pc_store + pc), - .B(alu_out), - .C(memory_out), - .D(0), - .S(input_reg), - .O(input_d) + .A(alu_out), + .B(memory_out), + .C(pc_addr + 4), + .D(pc_addr + alu_out), + .S(reg_sel_data_in), + .O(reg_data_in) ); endmodule -- 2.30.2 From dc087b24f228815df4fe10e627ab4e8f285addd2 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 11:32:25 +0900 Subject: [PATCH 08/17] Add: set R[0] to 0 --- rtl/registers_bank.v | 29 ++++------------------------- rtl/risc_v_cpu.v | 26 ++++++++++++-------------- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/rtl/registers_bank.v b/rtl/registers_bank.v index e60ba2e..b338862 100644 --- a/rtl/registers_bank.v +++ b/rtl/registers_bank.v @@ -1,41 +1,20 @@ module registers_bank (input clock, reset, we, input [4:0] sel_in, sel_out_a, sel_out_b, input [31:0] data_in, - output [31:0] output_a, output_b); + output [31:0] data_out_a, data_out_b); reg [31:0] registers[31:0]; assign registers[0] = 32'b0; - assign registers[1] = 32'b0; - assign registers[2] = 32'b0; - assign registers[3] = 32'b0; - assign registers[4] = 32'b0; - assign registers[5] = 32'b0; - assign registers[6] = 32'b0; - assign registers[7] = 32'b0; - assign registers[8] = 32'b0; - assign registers[9] = 32'b0; - assign registers[10] = 32'b0; - assign registers[11] = 32'b0; - assign registers[12] = 32'b0; - assign registers[13] = 32'b0; - assign registers[14] = 32'b0; - assign registers[15] = 32'b0; - assign registers[16] = 32'b0; - assign registers[17] = 32'b0; - assign registers[18] = 32'b0; - assign registers[19] = 32'b0; - assign registers[20] = 32'b0; - assign registers[21] = 32'b0; always @(posedge clock, posedge reset) begin if (reset == 1) registers[0] <= 32'b0; - else if (we == 1) + else if (we == 1 && sel_in != 5'b00000) registers[sel_in] <= data_in; end - assign output_a = registers[sel_out_a]; - assign output_b = registers[sel_out_b]; + assign data_out_a = registers[sel_out_a]; + assign data_out_b = registers[sel_out_b]; endmodule diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index e5b3ea7..e62cc53 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -1,24 +1,23 @@ module risc_v_cpu (input clock, reset, output [31:0] out); - wire [31:0] alu_in_b; - wire [31:0] alu_out; wire alu_src, alu_not; wire [3:0] alu_func; + wire [31:0] alu_in_b, alu_out; - wire reg_we, adder_pc; + wire reg_we; wire [1:0] reg_sel_data_in; wire [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in; + wire [31:0] reg_data_out_a, reg_data_out_b, reg_data_in; wire [31:0] instruction; wire mem_we; + wire [31:0] mem_out; wire [1:0] jmp_pc; wire b_pc; - wire [31:0] reg_data_in; - wire [31:0] output_a, output_b; - + wire adder_pc; wire [31:0] imm; wire [31:0] pc_addr; @@ -26,7 +25,6 @@ module risc_v_cpu (input clock, reset, output [31:0] out); wire [1:0] pc_in; - wire [31:0] memory_out; wire [31:0] pc_store; @@ -55,19 +53,19 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .sel_out_a(reg_sel_out_a), .sel_out_b(reg_sel_out_b), .data_in(reg_data_in), - .output_a(output_a), - .output_b(output_b) + .data_out_a(reg_data_out_a), + .data_out_b(reg_data_out_b) ); mux2_1 mux2_1_1 ( - .A(output_b), + .A(reg_data_out_b), .B(imm), .S(alu_src), .O(alu_in_b) ); alu alu ( - .input_a(output_a), + .input_a(reg_data_out_a), .input_b(alu_in_b), .op_code(alu_func), .out(alu_out) @@ -106,13 +104,13 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .reset(reset), .we(mem_we), .address(alu_out), - .data_in(output_b), - .data_out(memory_out) + .data_in(reg_data_out_b), + .data_out(mem_out) ); mux4_1 mux4_1_2 ( .A(alu_out), - .B(memory_out), + .B(mem_out), .C(pc_addr + 4), .D(pc_addr + alu_out), .S(reg_sel_data_in), -- 2.30.2 From c1a099c75d65d8328ec9d2c3efba2aee41fb0773 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 11:37:10 +0900 Subject: [PATCH 09/17] Fix: remove useless control signal --- rtl/decoder.v | 12 +----------- rtl/risc_v_cpu.v | 9 +++------ 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/rtl/decoder.v b/rtl/decoder.v index b254ac0..ca94e38 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -1,6 +1,6 @@ module decoder (input [31:0] instruction, output reg [31:0] imm, - output reg reg_we, adder_pc, + output reg reg_we, output reg [1:0] reg_sel_data_in, output reg [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in, output reg alu_src, @@ -81,7 +81,6 @@ endfunction OP : begin // OP - Add, ... imm = 0; reg_we = 1; - adder_pc = 0; reg_sel_data_in = 2'b00; reg_sel_out_a = instruction[19:15]; reg_sel_out_b = instruction[24:20]; @@ -97,7 +96,6 @@ endfunction imm[11:0] = instruction[31:20]; imm[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; reg_we = 1; - adder_pc = 0; reg_sel_data_in = 2'b00; reg_sel_out_a = instruction[19:15]; reg_sel_out_b = 5'b00000; @@ -113,7 +111,6 @@ endfunction imm[11:0] = instruction[31:20]; imm[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; reg_we = 1; - adder_pc = 0; reg_sel_data_in = 2'b01; reg_sel_out_a = instruction[19:15]; reg_sel_out_b = 5'b00000; @@ -129,7 +126,6 @@ endfunction imm[11:0] = {instruction[31:25], instruction[11:7]}; imm[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; reg_we = 0; - adder_pc = 0; reg_sel_data_in = 2'b00; reg_sel_out_a = instruction[19:15]; reg_sel_out_b = instruction[24:20]; @@ -145,7 +141,6 @@ endfunction imm[11:0] = {instruction[31:25], instruction[11:7]}; imm[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; reg_we = 0; - adder_pc = 0; reg_sel_data_in = 2'b00; reg_sel_out_a = instruction[19:15]; reg_sel_out_b = instruction[24:20]; @@ -161,7 +156,6 @@ endfunction imm[19:0] = instruction[31:12]; imm[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; reg_we = 1; - adder_pc = 0; reg_sel_data_in = 2'b10; reg_sel_out_a = 5'b00000; reg_sel_out_b = 5'b00000; @@ -177,7 +171,6 @@ endfunction imm[11:0] = instruction[31:20]; imm[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; reg_we = 1; - adder_pc = 0; reg_sel_data_in = 2'b10; reg_sel_out_a = instruction[19:15]; reg_sel_out_b = 5'b00000; @@ -192,7 +185,6 @@ endfunction LUI : begin // LUI - lui imm = {instruction[31:12] << 12, 12'b000000000000}; reg_we = 1; - adder_pc = 0; reg_sel_data_in = 2'b00; reg_sel_out_a = 5'b00000; reg_sel_out_b = 5'b00000; @@ -207,7 +199,6 @@ endfunction AUIPC : begin // AUIPC - auipc imm = {instruction[31:12] << 12, 12'b000000000000}; reg_we = 1; - adder_pc = 1; reg_sel_data_in = 2'b11; reg_sel_out_a = 5'b00000; reg_sel_out_b = 5'b00000; @@ -222,7 +213,6 @@ endfunction default : begin // NOP imm = 32'b0; reg_we = 0; - adder_pc = 0; reg_sel_data_in = 2'b00; reg_sel_out_a = 5'b00000; reg_sel_out_b = 5'b00000; diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index e62cc53..91bca22 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -17,14 +17,12 @@ module risc_v_cpu (input clock, reset, output [31:0] out); wire [1:0] jmp_pc; wire b_pc; - wire adder_pc; wire [31:0] imm; + wire [1:0] pc_sel_in; wire [31:0] pc_addr; wire [31:0] pc_new_addr; - wire [1:0] pc_in; - wire [31:0] pc_store; @@ -32,7 +30,6 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .instruction(instruction), .imm(imm), .reg_we(reg_we), - .adder_pc(adder_pc), .reg_sel_data_in(reg_sel_data_in), .reg_sel_out_a(reg_sel_out_a), .reg_sel_out_b(reg_sel_out_b), @@ -75,7 +72,7 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .A(jmp_pc), .B({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}), .S(b_pc), - .O(pc_in) + .O(pc_sel_in) ); mux4_1 mux4_1_1 ( @@ -83,7 +80,7 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .B(pc_addr + imm), .C(alu_out), .D(0), - .S(pc_in), + .S(pc_sel_in), .O(pc_new_addr) ); -- 2.30.2 From 2c9abe91afb5c13b3586867272454ef2c155fbe7 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 11:47:43 +0900 Subject: [PATCH 10/17] Fix: clean name [2] --- rtl/decoder.v | 44 ++++++++++++++++++++++---------------------- rtl/risc_v_cpu.v | 34 ++++++++++++++-------------------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/rtl/decoder.v b/rtl/decoder.v index ca94e38..debc358 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -6,8 +6,8 @@ module decoder (input [31:0] instruction, output reg alu_src, output reg [3:0] alu_func, output reg mem_we, - output reg [1:0] jmp_pc, - output reg b_pc, alu_not); + output reg [1:0] pc_is_branch, + output reg pc_is_jmp, alu_not); `include "op_code.vh" @@ -88,8 +88,8 @@ endfunction alu_src = 0; alu_func = get_alu_func(instruction[14:12], instruction[30]); mem_we = 0; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end OP_IMM : begin // OP-IMM - Addi, ... @@ -103,8 +103,8 @@ endfunction alu_src = 1; alu_func = get_alu_func_imm(instruction[14:12], instruction[30]); mem_we = 0; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end LOAD : begin // LOAD - Lw, ... @@ -118,8 +118,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 0; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end STORE : begin // STORE - Sw, ... @@ -133,8 +133,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 1; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end BRANCH : begin // BRANCH - Beq, ... @@ -148,8 +148,8 @@ endfunction alu_src = 0; alu_func = branch_op_code(instruction[14:12]); mem_we = 0; - jmp_pc = 2'b00; - b_pc = 1; + pc_is_branch = 2'b00; + pc_is_jmp = 1; alu_not = branch_not(instruction[14:12]); end JAL : begin // JUMP - Jal @@ -163,8 +163,8 @@ endfunction alu_src = 0; alu_func = 3'b000; mem_we = 0; - jmp_pc = 2'b01; - b_pc = 0; + pc_is_branch = 2'b01; + pc_is_jmp = 0; alu_not = 0; end JALR : begin // JUMP REG - Jalr @@ -178,8 +178,8 @@ endfunction alu_src = 0; alu_func = 3'b000; mem_we = 0; - jmp_pc = 2'b10; - b_pc = 0; + pc_is_branch = 2'b10; + pc_is_jmp = 0; alu_not = 0; end LUI : begin // LUI - lui @@ -192,8 +192,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 0; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end AUIPC : begin // AUIPC - auipc @@ -206,8 +206,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 0; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end default : begin // NOP @@ -220,8 +220,8 @@ endfunction alu_src = 0; alu_func = 3'b000; mem_we = 0; - jmp_pc = 2'b00; - b_pc = 0; + pc_is_branch = 2'b00; + pc_is_jmp = 0; alu_not = 0; end endcase diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index 91bca22..7985ce1 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -1,30 +1,24 @@ module risc_v_cpu (input clock, reset, output [31:0] out); - - wire alu_src, alu_not; - wire [3:0] alu_func; - wire [31:0] alu_in_b, alu_out; + + wire [31:0] instruction; + + wire [31:0] imm; wire reg_we; wire [1:0] reg_sel_data_in; wire [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in; wire [31:0] reg_data_out_a, reg_data_out_b, reg_data_in; - wire [31:0] instruction; + wire alu_src, alu_not; + wire [3:0] alu_func; + wire [31:0] alu_in_b, alu_out; wire mem_we; wire [31:0] mem_out; - wire [1:0] jmp_pc; - wire b_pc; - - wire [31:0] imm; - - wire [1:0] pc_sel_in; - wire [31:0] pc_addr; - wire [31:0] pc_new_addr; - - - wire [31:0] pc_store; + wire pc_is_jmp; + wire [1:0] pc_is_branch, pc_sel_in; + wire [31:0] pc_addr, pc_new_addr; decoder decoder ( .instruction(instruction), @@ -37,8 +31,8 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .alu_src(alu_src), .alu_func(alu_func), .mem_we(mem_we), - .jmp_pc(jmp_pc), - .b_pc(b_pc), + .pc_is_branch(pc_is_branch), + .pc_is_jmp(pc_is_jmp), .alu_not(alu_not) ); @@ -69,9 +63,9 @@ module risc_v_cpu (input clock, reset, output [31:0] out); ); mux2_1 #(2) mux2_1_2 ( - .A(jmp_pc), + .A(pc_is_branch), .B({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}), - .S(b_pc), + .S(pc_is_jmp), .O(pc_sel_in) ); -- 2.30.2 From 72d688018bcb0430fcc55f5f1d89d5a4f166cb48 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 14:15:21 +0900 Subject: [PATCH 11/17] Fix: clean name [3] --- rtl/alu.v | 22 ++++++------ rtl/instruction.v | 21 ++--------- rtl/memory.v | 10 +++--- rtl/mux2_1.v | 8 ++--- rtl/mux4_1.v | 10 +++--- rtl/program_counter.v | 6 ++-- rtl/registers_bank.v | 6 ++-- rtl/risc_v_cpu.v | 55 ++++++++++++++-------------- tb/tb_alu.v | 61 +++++++++++++++---------------- tb/tb_mux2_1.v | 84 ++++++++++++++++--------------------------- tb/tb_risc_v_cpu.v | 48 +++++++++++-------------- 11 files changed, 140 insertions(+), 191 deletions(-) diff --git a/rtl/alu.v b/rtl/alu.v index b159d3e..5c47920 100644 --- a/rtl/alu.v +++ b/rtl/alu.v @@ -1,18 +1,18 @@ -module alu (input [31:0] input_a, input_b, - input [3:0] op_code, +module alu (input [31:0] in_a, in_b, + input [3:0] op_code, output reg [31:0] out); always@ (*) begin case (op_code) - 4'b0000 : out <= input_a + input_b; - 4'b0001 : out <= input_a - input_b; - 4'b0010 : out <= input_a << input_b; - 4'b0011 : out <= (input_a < input_b) ? 1 : 0; - 4'b0100 : out <= input_a ^ input_b; - 4'b0101 : out <= input_a >> input_b; - 4'b0111 : out <= input_a >>> input_b; - 4'b1000 : out <= input_a | input_b; - 4'b1001 : out <= input_a & input_b; + 4'b0000 : out <= in_a + in_b; + 4'b0001 : out <= in_a - in_b; + 4'b0010 : out <= in_a << in_b; + 4'b0011 : out <= (in_a < in_b) ? 1 : 0; + 4'b0100 : out <= in_a ^ in_b; + 4'b0101 : out <= in_a >> in_b; + 4'b0111 : out <= in_a >>> in_b; + 4'b1000 : out <= in_a | in_b; + 4'b1001 : out <= in_a & in_b; default : out <= 32'b0; endcase end diff --git a/rtl/instruction.v b/rtl/instruction.v index 8ac4e87..3968c54 100644 --- a/rtl/instruction.v +++ b/rtl/instruction.v @@ -1,5 +1,5 @@ -module instruction (input [31:0] address, - output [31:0] instruction); +module instruction (input [31:0] address, + output [31:0] instruction); reg [31:0] memory [63:0]; @@ -30,20 +30,3 @@ module instruction (input [31:0] address, assign instruction = memory[address]; endmodule - -// -- result(1) := "00000000001100110000010000010000"; - -// -- "000000000000_00000_000_00110_0010000" -// result(0) := "00000000000100000000001100010000"; -// -- "000000000001_00000_000_00111_0010000" -// result(1) := "00000000000000000000001110010000"; - -// -- "000000000000_00110_000_01000_0010000" -// result(2) := "00000000000000110000010000010000"; -// -- "0000000_00111_00110_000_00110_0110000" -// result(3) := "00000000011100110000001100110000"; -// -- "000000000000_01000_000_00111_0010000" -// result(4) := "00000000000001000000001110010000"; - -// -- 111111111111_11111_110_00111_1101100 -// result(5) := "11111111111111111101001111101100"; \ No newline at end of file diff --git a/rtl/memory.v b/rtl/memory.v index 0c6f8e7..d2bd7a2 100644 --- a/rtl/memory.v +++ b/rtl/memory.v @@ -1,8 +1,8 @@ -module memory (input clock, reset, - input we, - input [31:0] address, - input [31:0] data_in, - output [31:0] data_out); +module memory (input clock, reset, + input we, + input [31:0] address, + input [31:0] data_in, + output [31:0] data_out); reg [63:0] memory [31:0]; diff --git a/rtl/mux2_1.v b/rtl/mux2_1.v index 267a48e..ed650c8 100644 --- a/rtl/mux2_1.v +++ b/rtl/mux2_1.v @@ -1,8 +1,8 @@ module mux2_1 #(parameter BUS_SIZE = 32) - (input [BUS_SIZE - 1:0] A, B, - input S, - output [BUS_SIZE - 1:0] O); + (input [BUS_SIZE - 1:0] in_1, in_2, + input sel, + output [BUS_SIZE - 1:0] out); - assign O = S ? B : A; + assign out = sel ? in_2 : in_1; endmodule \ No newline at end of file diff --git a/rtl/mux4_1.v b/rtl/mux4_1.v index 8c6b3c0..8e31303 100644 --- a/rtl/mux4_1.v +++ b/rtl/mux4_1.v @@ -1,9 +1,9 @@ module mux4_1 #(parameter BUS_SIZE = 32) - (input [BUS_SIZE - 1:0] A, B, C, D, - input [1:0] S, - output [BUS_SIZE - 1:0] O); + (input [BUS_SIZE - 1:0] in_1, in_2, in_3, in_4, + input [1:0] sel, + output [BUS_SIZE - 1:0] out); - assign O = S[1] ? (S[0] ? D : C) - : (S[0] ? B : A); + assign out = sel[1] ? (sel[0] ? in_4 : in_3) + : (sel[0] ? in_2 : in_1); endmodule diff --git a/rtl/program_counter.v b/rtl/program_counter.v index 8345db8..f647764 100644 --- a/rtl/program_counter.v +++ b/rtl/program_counter.v @@ -1,6 +1,6 @@ -module program_counter (input clock, reset, - input [31:0] pc_new_addr, - output reg [31:0] pc_addr); +module program_counter (input clock, reset, + input [31:0] pc_new_addr, + output reg [31:0] pc_addr); always @ (posedge clock, posedge reset) begin if (reset == 1'b1) diff --git a/rtl/registers_bank.v b/rtl/registers_bank.v index b338862..31c5225 100644 --- a/rtl/registers_bank.v +++ b/rtl/registers_bank.v @@ -1,6 +1,6 @@ -module registers_bank (input clock, reset, we, - input [4:0] sel_in, sel_out_a, sel_out_b, - input [31:0] data_in, +module registers_bank (input clock, reset, we, + input [4:0] sel_in, sel_out_a, sel_out_b, + input [31:0] data_in, output [31:0] data_out_a, data_out_b); reg [31:0] registers[31:0]; diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index 7985ce1..2770d01 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -1,4 +1,5 @@ -module risc_v_cpu (input clock, reset, output [31:0] out); +module risc_v_cpu (input clock, reset, + output [31:0] out); wire [31:0] instruction; @@ -48,34 +49,34 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .data_out_b(reg_data_out_b) ); - mux2_1 mux2_1_1 ( - .A(reg_data_out_b), - .B(imm), - .S(alu_src), - .O(alu_in_b) + mux2_1 mux2_alu_in_b ( + .in_1(reg_data_out_b), + .in_2(imm), + .sel(alu_src), + .out(alu_in_b) ); alu alu ( - .input_a(reg_data_out_a), - .input_b(alu_in_b), + .in_a(reg_data_out_a), + .in_b(alu_in_b), .op_code(alu_func), .out(alu_out) ); - mux2_1 #(2) mux2_1_2 ( - .A(pc_is_branch), - .B({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}), - .S(pc_is_jmp), - .O(pc_sel_in) + mux2_1 #(2) mux2_pc_sel_branch ( + .in_1(pc_is_branch), + .in_2({alu_out[1], (alu_not ? ~alu_out[0] : alu_out[0])}), + .sel(pc_is_jmp), + .out(pc_sel_in) ); - mux4_1 mux4_1_1 ( - .A(pc_addr + 4), - .B(pc_addr + imm), - .C(alu_out), - .D(0), - .S(pc_sel_in), - .O(pc_new_addr) + mux4_1 mux4_pc_sel_in ( + .in_1(pc_addr + 4), + .in_2(pc_addr + imm), + .in_3(alu_out), + .in_4(0), + .sel(pc_sel_in), + .out(pc_new_addr) ); program_counter program_counter ( @@ -99,13 +100,13 @@ module risc_v_cpu (input clock, reset, output [31:0] out); .data_out(mem_out) ); - mux4_1 mux4_1_2 ( - .A(alu_out), - .B(mem_out), - .C(pc_addr + 4), - .D(pc_addr + alu_out), - .S(reg_sel_data_in), - .O(reg_data_in) + mux4_1 mux4_reg_sel_data_in ( + .in_1(alu_out), + .in_2(mem_out), + .in_3(pc_addr + 4), + .in_4(pc_addr + alu_out), + .sel(reg_sel_data_in), + .out(reg_data_in) ); endmodule diff --git a/tb/tb_alu.v b/tb/tb_alu.v index c9f80d9..39dcf26 100644 --- a/tb/tb_alu.v +++ b/tb/tb_alu.v @@ -1,41 +1,36 @@ `timescale 1ns / 1ps module tb_alu (); -// Design Inputs and outputs -reg [31:0] in_a; -reg [31:0] in_b; -reg [2:0] op_code; -wire [31:0] out; + reg [31:0] in_a; + reg [31:0] in_b; + reg [2:0] op_code; + wire [31:0] out; -// DUT instantiation -alu alu ( - .input_a(in_a), - .input_b(in_b), - .op_code(op_code), - .out(out) -); + alu alu ( + .in_a(in_a), + .in_b(in_b), + .op_code(op_code), + .out(out) + ); -// Test stimulus -initial begin - // Use the monitor task to display the FPGA IO - $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", - $time, in_a, in_b, op_code, out); + initial begin + $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", + $time, in_a, in_b, op_code, out); - // Generate each input with a 20 ns delay between them - in_a = 1'b0; - in_b = 1'b0; - op_code = 3'b000; - #20 - if (out !== 0) $display("[FAILED] output should be 0"); - in_a = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); - in_b = 1'b1; - #20 - if (out !== 2) $display("[FAILED] output should be 2"); - op_code = 3'b001; - #20 - if (out !== 2) $display("[FAILED] output should be 2"); -end + in_a = 1'b0; + in_b = 1'b0; + op_code = 3'b000; + #20 + if (out !== 0) $display("[FAILED] output should be 0"); + in_a = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + in_b = 1'b1; + #20 + if (out !== 2) $display("[FAILED] output should be 2"); + op_code = 3'b001; + #20 + if (out !== 2) $display("[FAILED] output should be 2"); + end endmodule : tb_alu diff --git a/tb/tb_mux2_1.v b/tb/tb_mux2_1.v index b36081f..cd7bc39 100644 --- a/tb/tb_mux2_1.v +++ b/tb/tb_mux2_1.v @@ -1,61 +1,39 @@ `timescale 1ns / 1ps module tb_mux2_1 (); -// Clock and reset signals -reg clk; -reg reset; + reg ctrl; + reg [31:0] in_a; + reg [31:0] in_b; + wire [31:0] out; -// Design Inputs and outputs -reg [31:0] in_a; -reg [31:0] in_b; -reg ctrl; -wire [31:0] out; + mux2_1 mux ( + .S(ctrl), + .A(in_a), + .B(in_b), + .O(out) + ); -// DUT instantiation -mux2_1 mux ( - .S(ctrl), - .A(in_a), - .B(in_b), - .O(out) -); + initial begin + $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", + $time, in_a, in_b, ctrl, out); -// generate the clock -initial begin - clk = 1'b0; - // forever #1 clk = ~clk; -end - -// Generate the reset -initial begin - reset = 1'b1; - #10 - reset = 1'b0; -end - -// Test stimulus -initial begin - // Use the monitor task to display the FPGA IO - $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", - $time, in_a, in_b, ctrl, out); - - // Generate each input with a 20 ns delay between them - in_a = 1'b0; - in_b = 1'b0; - ctrl = 1'b0; - #20 - if (out !== 0) $display("[FAILED] output should be 0"); - in_a = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); - ctrl = 1'b1; - in_a = 1'b0; - in_b = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); - ctrl = 1'b0; - in_a = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); -end + in_a = 1'b0; + in_b = 1'b0; + ctrl = 1'b0; + #20 + if (out !== 0) $display("[FAILED] output should be 0"); + in_a = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + ctrl = 1'b1; + in_a = 1'b0; + in_b = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + ctrl = 1'b0; + in_a = 1'b1; + #20 + if (out !== 1) $display("[FAILED] output should be 1"); + end endmodule : tb_mux2_1 diff --git a/tb/tb_risc_v_cpu.v b/tb/tb_risc_v_cpu.v index 41852e0..8cdabf5 100644 --- a/tb/tb_risc_v_cpu.v +++ b/tb/tb_risc_v_cpu.v @@ -1,36 +1,28 @@ `timescale 1ns / 1ps module tb_risc_v_cpu (); -integer i; + reg clk; + reg reset; + integer i; + wire [31:0] out; -// Clock and reset signals -reg clk; -reg reset; + risc_v_cpu risc_v_cpu ( + .clock(clk), + .reset(reset), + .out(out) + ); -// Design Inputs and outputs -wire [31:0] out; - -// DUT instantiation -risc_v_cpu risc_v_cpu ( - .clock(clk), - .reset(reset), - .out(out) -); - -// Generate the reset -initial begin - reset = 1'b1; - #10 - reset = 1'b0; -end - - -// generate the clock -initial begin - clk = 1'b0; - for (i = 0; i < 100; i = i + 1) begin - #1 clk = ~clk; + initial begin + reset = 1'b1; + #10 + reset = 1'b0; + end + + initial begin + clk = 1'b0; + for (i = 0; i < 100; i = i + 1) begin + #1 clk = ~clk; + end end -end endmodule : tb_risc_v_cpu -- 2.30.2 From 5829400fea31c6609d74b2d5513ac09ee4bcc32e Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 23 Oct 2023 17:34:37 +0900 Subject: [PATCH 12/17] Add: tb macro to assert --- tb/tb_alu.v | 30 ++++++++++++-------------- tb/tb_mux2_1.v | 52 +++++++++++++++++++++++----------------------- tb/tb_risc_v_cpu.v | 1 + tb/tb_tools.vh | 7 +++++++ 4 files changed, 47 insertions(+), 43 deletions(-) create mode 100644 tb/tb_tools.vh diff --git a/tb/tb_alu.v b/tb/tb_alu.v index 39dcf26..d0d14f1 100644 --- a/tb/tb_alu.v +++ b/tb/tb_alu.v @@ -1,9 +1,10 @@ `timescale 1ns / 1ps +`include "tb_tools.vh" module tb_alu (); reg [31:0] in_a; reg [31:0] in_b; - reg [2:0] op_code; + reg [3:0] op_code; wire [31:0] out; alu alu ( @@ -14,23 +15,18 @@ module tb_alu (); ); initial begin - $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", - $time, in_a, in_b, op_code, out); + in_a = 32'b0; + in_b = 32'b0; + op_code = 4'b0000; + `assert("alu : 0 + 0", out, 0) + in_a = 32'b1; + `assert("alu : 1 + 0", out, 1) + in_b = 32'b1; + `assert("alu : 1 + 1", out, 2) + op_code = 4'b0001; + `assert("alu : 1 - 1", out, 0) - in_a = 1'b0; - in_b = 1'b0; - op_code = 3'b000; - #20 - if (out !== 0) $display("[FAILED] output should be 0"); - in_a = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); - in_b = 1'b1; - #20 - if (out !== 2) $display("[FAILED] output should be 2"); - op_code = 3'b001; - #20 - if (out !== 2) $display("[FAILED] output should be 2"); + `end_message end endmodule : tb_alu diff --git a/tb/tb_mux2_1.v b/tb/tb_mux2_1.v index cd7bc39..4e736d7 100644 --- a/tb/tb_mux2_1.v +++ b/tb/tb_mux2_1.v @@ -1,39 +1,39 @@ `timescale 1ns / 1ps +`include "tb_tools.vh" module tb_mux2_1 (); - reg ctrl; - reg [31:0] in_a; - reg [31:0] in_b; + + reg sel; + reg [31:0] in_1; + reg [31:0] in_2; wire [31:0] out; mux2_1 mux ( - .S(ctrl), - .A(in_a), - .B(in_b), - .O(out) + .in_1(in_1), + .in_2(in_2), + .sel(sel), + .out(out) ); initial begin - $monitor("time=%3d, in_a=%d, in_b=%d, ctrl=%b, q=%d \n", - $time, in_a, in_b, ctrl, out); + in_1 = 1'b0; + in_2 = 1'b0; + sel = 1'b0; + `assert("mux in_1: 0, in_2: 0, sel: 0", out, 0) + in_1 = 1'b1; + `assert("mux in_1: 1, in_2: 0, sel: 0", out, 1) + sel = 1'b1; + `assert("mux in_1: 1, in_2: 0, sel: 1", out, 0) + in_2 = 1'b1; + `assert("mux in_1: 1, in_2: 1, sel: 1", out, 1) + in_1 = 1'b0; + `assert("mux in_1: 0, in_2: 1, sel: 1", out, 1) + in_2 = 1'b0; + `assert("mux in_1: 0, in_2: 0, sel: 1", out, 0) + sel = 1'b0; + `assert("mux in_1: 0, in_2: 0, sel: 0", out, 0) - in_a = 1'b0; - in_b = 1'b0; - ctrl = 1'b0; - #20 - if (out !== 0) $display("[FAILED] output should be 0"); - in_a = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); - ctrl = 1'b1; - in_a = 1'b0; - in_b = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); - ctrl = 1'b0; - in_a = 1'b1; - #20 - if (out !== 1) $display("[FAILED] output should be 1"); + `end_message end endmodule : tb_mux2_1 diff --git a/tb/tb_risc_v_cpu.v b/tb/tb_risc_v_cpu.v index 8cdabf5..f7d9988 100644 --- a/tb/tb_risc_v_cpu.v +++ b/tb/tb_risc_v_cpu.v @@ -1,4 +1,5 @@ `timescale 1ns / 1ps +`include "tb_tools.vh" module tb_risc_v_cpu (); reg clk; diff --git a/tb/tb_tools.vh b/tb/tb_tools.vh new file mode 100644 index 0000000..d8774c8 --- /dev/null +++ b/tb/tb_tools.vh @@ -0,0 +1,7 @@ +`define assert(message, expected, got) \ + #20 \ + if(expected !== got) begin \ + $display("\033[0;31m[FAILED]\033[0m : %s - got: %d, expected: %d", message, expected, got); \ + end + +`define end_message $display("\033[0;32mIf no \033[0m[FAILED]\033[0;32m messages, all tests passed!\033[0m"); -- 2.30.2 From b99914f42d1b8fdf2dfeb95fe505ecb000600544 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Tue, 24 Oct 2023 10:49:29 +0900 Subject: [PATCH 13/17] Add: named parameter for ALU func | alu test case --- rtl/alu.v | 21 ++++++----- rtl/alu_func.vh | 10 +++++ rtl/decoder.v | 35 +++++++++--------- tb/tb_alu.v | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 135 insertions(+), 28 deletions(-) create mode 100644 rtl/alu_func.vh diff --git a/rtl/alu.v b/rtl/alu.v index 5c47920..486ff0a 100644 --- a/rtl/alu.v +++ b/rtl/alu.v @@ -2,17 +2,20 @@ module alu (input [31:0] in_a, in_b, input [3:0] op_code, output reg [31:0] out); + `include "alu_func.vh" + always@ (*) begin case (op_code) - 4'b0000 : out <= in_a + in_b; - 4'b0001 : out <= in_a - in_b; - 4'b0010 : out <= in_a << in_b; - 4'b0011 : out <= (in_a < in_b) ? 1 : 0; - 4'b0100 : out <= in_a ^ in_b; - 4'b0101 : out <= in_a >> in_b; - 4'b0111 : out <= in_a >>> in_b; - 4'b1000 : out <= in_a | in_b; - 4'b1001 : out <= in_a & in_b; + ADD : out <= in_a + in_b; + SUB : out <= in_a - in_b; + SLL : out <= in_a << in_b; + SLT : out <= ((in_a[31] != in_b[31]) ? in_a[31] == 1'b1 : in_a < in_b) ? 1 : 0; + SLTU : out <= (in_a < in_b) ? 1 : 0; + XOR : out <= in_a ^ in_b; + SRL : out <= in_a >> in_b; + SRA : out <= in_a >>> in_b; + OR : out <= in_a | in_b; + AND : out <= in_a & in_b; default : out <= 32'b0; endcase end diff --git a/rtl/alu_func.vh b/rtl/alu_func.vh new file mode 100644 index 0000000..8b4142c --- /dev/null +++ b/rtl/alu_func.vh @@ -0,0 +1,10 @@ +parameter [3:0] ADD = 4'b0000; +parameter [3:0] SUB = 4'b0001; +parameter [3:0] SLL = 4'b0010; +parameter [3:0] SLT = 4'b0011; +parameter [3:0] SLTU = 4'b0100; +parameter [3:0] XOR = 4'b0101; +parameter [3:0] SRL = 4'b0110; +parameter [3:0] SRA = 4'b0111; +parameter [3:0] OR = 4'b1000; +parameter [3:0] AND = 4'b1001; \ No newline at end of file diff --git a/rtl/decoder.v b/rtl/decoder.v index debc358..46b74aa 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -10,19 +10,19 @@ module decoder (input [31:0] instruction, output reg pc_is_jmp, alu_not); `include "op_code.vh" +`include "alu_func.vh" function [3:0] get_alu_func(input [2:0] op_code, input arithmetic); begin case (op_code) - 3'b000 : get_alu_func = arithmetic ? 4'b0001 : 4'b0000; - 3'b001 : get_alu_func = 4'b0010; - 3'b010 : get_alu_func = 4'b0011; - 3'b011 : get_alu_func = 4'b0011; - 3'b100 : get_alu_func = 4'b0100; - 3'b101 : get_alu_func = arithmetic ? 4'b0111 : 4'b0101; - 3'b110 : get_alu_func = 4'b1000; - 3'b111 : get_alu_func = 4'b1010; - 3'b111 : get_alu_func = 4'b1011; + 3'b000 : get_alu_func = arithmetic ? SUB : ADD; + 3'b001 : get_alu_func = SLL; + 3'b010 : get_alu_func = SLT; + 3'b011 : get_alu_func = SLTU; + 3'b100 : get_alu_func = XOR; + 3'b101 : get_alu_func = arithmetic ? SRA : SRL; + 3'b110 : get_alu_func = OR; + 3'b111 : get_alu_func = AND; default : get_alu_func= 4'b0000; endcase end @@ -31,15 +31,14 @@ endfunction function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic); begin case (op_code) - 3'b000 : get_alu_func_imm = 4'b0000; - 3'b001 : get_alu_func_imm = 4'b0010; - 3'b010 : get_alu_func_imm = 4'b0011; - 3'b011 : get_alu_func_imm = 4'b0100; - 3'b100 : get_alu_func_imm = 4'b0101; - 3'b101 : get_alu_func_imm = arithmetic ? 4'b1000 : 4'b0111; - 3'b110 : get_alu_func_imm = 4'b1001; - 3'b111 : get_alu_func_imm = 4'b1010; - 3'b111 : get_alu_func_imm = 4'b1011; + 3'b000 : get_alu_func_imm = ADD; + 3'b001 : get_alu_func_imm = SLL; + 3'b010 : get_alu_func_imm = SLT; + 3'b011 : get_alu_func_imm = SLTU; + 3'b100 : get_alu_func_imm = XOR; + 3'b101 : get_alu_func_imm = arithmetic ? SRA : SRL; + 3'b110 : get_alu_func_imm = OR; + 3'b111 : get_alu_func_imm = AND; default : get_alu_func_imm = 4'b0000; endcase end diff --git a/tb/tb_alu.v b/tb/tb_alu.v index d0d14f1..f05ad3a 100644 --- a/tb/tb_alu.v +++ b/tb/tb_alu.v @@ -2,6 +2,8 @@ `include "tb_tools.vh" module tb_alu (); + `include "../rtl/alu_func.vh" + reg [31:0] in_a; reg [31:0] in_b; reg [3:0] op_code; @@ -15,9 +17,10 @@ module tb_alu (); ); initial begin + // ALU - Add in_a = 32'b0; in_b = 32'b0; - op_code = 4'b0000; + op_code = ADD; `assert("alu : 0 + 0", out, 0) in_a = 32'b1; `assert("alu : 1 + 0", out, 1) @@ -26,6 +29,98 @@ module tb_alu (); op_code = 4'b0001; `assert("alu : 1 - 1", out, 0) + // ALU - left shift + in_a = 32'b1; + in_b = 32'b1; + op_code = SLL; + `assert("alu : 1 << 1", out, 2) + in_b = 32'b10; + `assert("alu : 1 << 2", out, 4) + in_a = 32'b11; + `assert("alu : 3 << 2", out, 12) + in_b = 32'b11110; + `assert("alu : 3 << 30", out, 32'b11000000000000000000000000000000) + in_b = 32'b11111; + `assert("alu : 3 << 31", out, 32'b10000000000000000000000000000000) + in_b = 32'b100000; + `assert("alu : 3 << 31", out, 32'b00000000000000000000000000000000) + + // ALU - less than + in_a = 32'b0; + in_b = 32'b0; + op_code = SLT; + `assert("alu : 0 < 0", out, 0) + in_b = 32'b10; + `assert("alu : 0 << 2", out, 1) + in_a = 32'b11; + `assert("alu : 3 < 2", out, 0) + in_b = 32'b11111111111111111111111111111111; + in_a = 32'b11111111111111111111111111111111; + `assert("alu : -1 < -1", out, 0) + in_b = 32'b0; + `assert("alu : -1 < 0", out, 1) + in_a = 32'b10000000000000000000000000000000; + in_b = 32'b10000000000000000000000000000001; + `assert("alu : MIN_INT << MIN_INT + 1", out, 1) + + // ALU - xor + in_a = 32'b0; + in_b = 32'b0; + op_code = XOR; + `assert("alu : 0 ^ 0", out, 32'b00000000000000000000000000000000) + in_a = 32'b1; + `assert("alu : 1 ^ 0", out, 32'b00000000000000000000000000000001) + in_a = 32'b0; + in_b = 32'b1; + `assert("alu : 0 ^ 1", out, 32'b00000000000000000000000000000001) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : MAX_INT ^ MAX_INT", out, 32'b00000000000000000000000000000000) + in_a = 32'b00000000000000000000000000000000; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : 0 ^ MAX_INT", out, 32'b11111111111111111111111111111111) + in_a = 32'b00000011001000010001000011000000; + in_b = 32'b10101111001011101110111111111011; + `assert("alu : 00000011001000010001000011000000 ^ 10101111001011101110111111111011", out, 32'b10101100000011111111111100111011) + + // ALU - right shift + in_a = 32'b1; + in_b = 32'b1; + op_code = SRL; + `assert("alu : 1 >> 1", out, 0) + in_a = 32'b10; + `assert("alu : 2 >> 1", out, 1) + in_a = 32'b11; + `assert("alu : 3 >> 2", out, 1) + in_a = 32'b11110; + in_b = 32'b1; + `assert("alu : 30 >> 1", out, 32'b1111) + in_a = 32'b10000000000000000000000000000000; + in_b = 32'b11111; + `assert("alu : 1000...000 >> 31", out, 32'b00000000000000000000000000000001) + in_a = 32'b10000000111100000000000111111111; + in_b = 32'b11111; + `assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001) + + // // ALU - logical right shift + // in_a = 32'b1; + // in_b = 32'b1; + // op_code = 4'b0110; + // `assert("alu : 1 >> 1", out, 0) + // in_a = 32'b10; + // `assert("alu : 2 >> 1", out, 1) + // in_a = 32'b11; + // `assert("alu : 3 >> 2", out, 1) + // in_a = 32'b11110; + // in_b = 32'b1; + // `assert("alu : 30 >> 1", out, 32'b1111) + // in_a = 32'b10000000000000000000000000000000; + // in_b = 32'b11111; + // `assert("alu : 1000...000 >> 31", out, 32'b00000000000000000000000000000001) + // in_a = 32'b10000000111100000000000111111111; + // in_b = 32'b11111; + // `assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001) + `end_message end -- 2.30.2 From 6cc27cdc2f1254818088aeb4bc28c533e990bc45 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Tue, 24 Oct 2023 19:36:34 +0900 Subject: [PATCH 14/17] Add: tb alu all func --- rtl/alu.v | 9 +++- tb/tb_alu.v | 126 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/rtl/alu.v b/rtl/alu.v index 486ff0a..8e7ed9d 100644 --- a/rtl/alu.v +++ b/rtl/alu.v @@ -3,17 +3,22 @@ module alu (input [31:0] in_a, in_b, output reg [31:0] out); `include "alu_func.vh" + + reg signed [31:0] s_in_a; + reg signed [31:0] s_in_b; always@ (*) begin + s_in_a = in_a; + s_in_b = in_b; case (op_code) ADD : out <= in_a + in_b; SUB : out <= in_a - in_b; SLL : out <= in_a << in_b; - SLT : out <= ((in_a[31] != in_b[31]) ? in_a[31] == 1'b1 : in_a < in_b) ? 1 : 0; + SLT : out <= (s_in_a < s_in_b) ? 1 : 0; SLTU : out <= (in_a < in_b) ? 1 : 0; XOR : out <= in_a ^ in_b; SRL : out <= in_a >> in_b; - SRA : out <= in_a >>> in_b; + SRA : out <= s_in_a >>> in_b; OR : out <= in_a | in_b; AND : out <= in_a & in_b; default : out <= 32'b0; diff --git a/tb/tb_alu.v b/tb/tb_alu.v index f05ad3a..3abc655 100644 --- a/tb/tb_alu.v +++ b/tb/tb_alu.v @@ -17,22 +17,58 @@ module tb_alu (); ); initial begin - // ALU - Add + // ALU - add + op_code = ADD; in_a = 32'b0; in_b = 32'b0; - op_code = ADD; `assert("alu : 0 + 0", out, 0) in_a = 32'b1; `assert("alu : 1 + 0", out, 1) in_b = 32'b1; `assert("alu : 1 + 1", out, 2) - op_code = 4'b0001; + in_a = 32'b0; + `assert("alu : 0 + 1", out, 1) + in_a = 32'b1111; + in_b = 32'b1111; + `assert("alu : 15 + 15", out, 30) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b00000000000000000000000000000000; + `assert("alu : 0 + -1", out, 32'b11111111111111111111111111111111) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b00000000000000000000000000000001; + `assert("alu : 1 + -1", out, 0) + in_a = 32'b10000000000000000000000000000000; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : MIN_INT + -1", out, 32'b01111111111111111111111111111111) + + // ALU - sub + op_code = SUB; + in_a = 32'b0; + in_b = 32'b0; + `assert("alu : 0 - 0", out, 0) + in_a = 32'b1; + `assert("alu : 1 - 0", out, 1) + in_b = 32'b1; `assert("alu : 1 - 1", out, 0) + in_a = 32'b0; + `assert("alu : 0 - 1", out, 32'b11111111111111111111111111111111) + in_a = 32'b11111; + in_b = 32'b1111; + `assert("alu : 31 - 15", out, 16) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b00000000000000000000000000000000; + `assert("alu : -1 - 0", out, 32'b11111111111111111111111111111111) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b00000000000000000000000000000001; + `assert("alu : -1 - 1", out, 32'b11111111111111111111111111111110) + in_a = 32'b10000000000000000000000000000000; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : MIN_INT - -1", out, 32'b10000000000000000000000000000001) // ALU - left shift + op_code = SLL; in_a = 32'b1; in_b = 32'b1; - op_code = SLL; `assert("alu : 1 << 1", out, 2) in_b = 32'b10; `assert("alu : 1 << 2", out, 4) @@ -46,9 +82,9 @@ module tb_alu (); `assert("alu : 3 << 31", out, 32'b00000000000000000000000000000000) // ALU - less than + op_code = SLT; in_a = 32'b0; in_b = 32'b0; - op_code = SLT; `assert("alu : 0 < 0", out, 0) in_b = 32'b10; `assert("alu : 0 << 2", out, 1) @@ -64,9 +100,9 @@ module tb_alu (); `assert("alu : MIN_INT << MIN_INT + 1", out, 1) // ALU - xor + op_code = XOR; in_a = 32'b0; in_b = 32'b0; - op_code = XOR; `assert("alu : 0 ^ 0", out, 32'b00000000000000000000000000000000) in_a = 32'b1; `assert("alu : 1 ^ 0", out, 32'b00000000000000000000000000000001) @@ -84,9 +120,9 @@ module tb_alu (); `assert("alu : 00000011001000010001000011000000 ^ 10101111001011101110111111111011", out, 32'b10101100000011111111111100111011) // ALU - right shift + op_code = SRL; in_a = 32'b1; in_b = 32'b1; - op_code = SRL; `assert("alu : 1 >> 1", out, 0) in_a = 32'b10; `assert("alu : 2 >> 1", out, 1) @@ -102,24 +138,64 @@ module tb_alu (); in_b = 32'b11111; `assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001) - // // ALU - logical right shift - // in_a = 32'b1; - // in_b = 32'b1; - // op_code = 4'b0110; - // `assert("alu : 1 >> 1", out, 0) - // in_a = 32'b10; - // `assert("alu : 2 >> 1", out, 1) - // in_a = 32'b11; - // `assert("alu : 3 >> 2", out, 1) - // in_a = 32'b11110; - // in_b = 32'b1; - // `assert("alu : 30 >> 1", out, 32'b1111) - // in_a = 32'b10000000000000000000000000000000; - // in_b = 32'b11111; - // `assert("alu : 1000...000 >> 31", out, 32'b00000000000000000000000000000001) - // in_a = 32'b10000000111100000000000111111111; - // in_b = 32'b11111; - // `assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001) + // ALU - arithmetic right shift + op_code = SRA; + in_a = 32'b1; + in_b = 32'b1; + `assert("alu : 1 >>> 1", out, 0) + in_a = 32'b10; + `assert("alu : 2 >>> 1", out, 1) + in_a = 32'b11; + `assert("alu : 3 >>> 2", out, 1) + in_a = 32'b11110; + in_b = 32'b1; + `assert("alu : 30 >>> 1", out, 32'b1111) + in_a = 32'b10000000000000000000000000000000; + in_b = 32'b11111; + `assert("alu : 1000...000 >>> 31", out, 32'b11111111111111111111111111111111) + in_a = 32'b10000000111100000000000111111111; + in_b = 32'b11111; + `assert("alu : 1000..111 >>> 31", out, 32'b11111111111111111111111111111111) + + // ALU - or + op_code = OR; + in_a = 32'b0; + in_b = 32'b0; + `assert("alu : 0 | 0", out, 32'b00000000000000000000000000000000) + in_a = 32'b1; + `assert("alu : 1 | 0", out, 32'b00000000000000000000000000000001) + in_a = 32'b0; + in_b = 32'b1; + `assert("alu : 0 | 1", out, 32'b00000000000000000000000000000001) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : MAX_INT | MAX_INT", out, 32'b11111111111111111111111111111111) + in_a = 32'b00000000000000000000000000000000; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : 0 | MAX_INT", out, 32'b11111111111111111111111111111111) + in_a = 32'b00000011001000010001000011000000; + in_b = 32'b10101111001011101110111111111011; + `assert("alu : 00000011001000010001000011000000 | 10101111001011101110111111111011", out, 32'b10101111001011111111111111111011) + + // ALU - and + op_code = AND; + in_a = 32'b0; + in_b = 32'b0; + `assert("alu : 0 & 0", out, 32'b00000000000000000000000000000000) + in_a = 32'b1; + `assert("alu : 1 & 0", out, 32'b00000000000000000000000000000000) + in_a = 32'b0; + in_b = 32'b1; + `assert("alu : 0 & 1", out, 32'b00000000000000000000000000000000) + in_a = 32'b11111111111111111111111111111111; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : MAX_INT & MAX_INT", out, 32'b11111111111111111111111111111111) + in_a = 32'b00000000000000000000000000000000; + in_b = 32'b11111111111111111111111111111111; + `assert("alu : 0 & MAX_INT", out, 32'b00000000000000000000000000000000) + in_a = 32'b00000011001000010001000011000000; + in_b = 32'b10101111001011101110111111111011; + `assert("alu : 00000011001000010001000011000000 & 10101111001011101110111111111011", out, 32'b00000011001000000000000011000000) `end_message end -- 2.30.2 From ecfb4a9cc5539cd30a879a99d8d20b9c36dc5eb3 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Tue, 24 Oct 2023 19:39:42 +0900 Subject: [PATCH 15/17] Fix: change alu op_code to func --- rtl/alu.v | 4 ++-- rtl/decoder.v | 32 ++++++++++++++++---------------- rtl/risc_v_cpu.v | 2 +- tb/tb_alu.v | 22 +++++++++++----------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/rtl/alu.v b/rtl/alu.v index 8e7ed9d..e472c87 100644 --- a/rtl/alu.v +++ b/rtl/alu.v @@ -1,5 +1,5 @@ module alu (input [31:0] in_a, in_b, - input [3:0] op_code, + input [3:0] func, output reg [31:0] out); `include "alu_func.vh" @@ -10,7 +10,7 @@ module alu (input [31:0] in_a, in_b, always@ (*) begin s_in_a = in_a; s_in_b = in_b; - case (op_code) + case (func) ADD : out <= in_a + in_b; SUB : out <= in_a - in_b; SLL : out <= in_a << in_b; diff --git a/rtl/decoder.v b/rtl/decoder.v index 46b74aa..0f9eeee 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -12,9 +12,9 @@ module decoder (input [31:0] instruction, `include "op_code.vh" `include "alu_func.vh" -function [3:0] get_alu_func(input [2:0] op_code, input arithmetic); +function [3:0] get_alu_func(input [2:0] func, input arithmetic); begin - case (op_code) + case (func) 3'b000 : get_alu_func = arithmetic ? SUB : ADD; 3'b001 : get_alu_func = SLL; 3'b010 : get_alu_func = SLT; @@ -28,9 +28,9 @@ function [3:0] get_alu_func(input [2:0] op_code, input arithmetic); end endfunction -function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic); +function [3:0] get_alu_func_imm(input [2:0] func, input arithmetic); begin - case (op_code) + case (func) 3'b000 : get_alu_func_imm = ADD; 3'b001 : get_alu_func_imm = SLL; 3'b010 : get_alu_func_imm = SLT; @@ -44,23 +44,23 @@ function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic); end endfunction -function [3:0] branch_op_code(input [2:0] op_code); +function [3:0] branch_func(input [2:0] func); begin - case (op_code) - 3'b000 : branch_op_code = 4'b0001; - 3'b001 : branch_op_code = 4'b0001; - 3'b010 : branch_op_code = 4'b0011; - 3'b011 : branch_op_code = 4'b0011; - 3'b100 : branch_op_code = 4'b0011; - 3'b101 : branch_op_code = 4'b0011; - default : branch_op_code = 4'b0000; + case (func) + 3'b000 : branch_func = 4'b0001; + 3'b001 : branch_func = 4'b0001; + 3'b010 : branch_func = 4'b0011; + 3'b011 : branch_func = 4'b0011; + 3'b100 : branch_func = 4'b0011; + 3'b101 : branch_func = 4'b0011; + default : branch_func = 4'b0000; endcase end endfunction -function branch_not(input [2:0] op_code); +function branch_not(input [2:0] func); begin - case (op_code) + case (func) 3'b000 : branch_not = 1; 3'b001 : branch_not = 0; 3'b010 : branch_not = 0; @@ -145,7 +145,7 @@ endfunction reg_sel_out_b = instruction[24:20]; reg_sel_in = 5'b00000; alu_src = 0; - alu_func = branch_op_code(instruction[14:12]); + alu_func = branch_func(instruction[14:12]); mem_we = 0; pc_is_branch = 2'b00; pc_is_jmp = 1; diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index 2770d01..7b1bdfe 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -59,7 +59,7 @@ module risc_v_cpu (input clock, reset, alu alu ( .in_a(reg_data_out_a), .in_b(alu_in_b), - .op_code(alu_func), + .func(alu_func), .out(alu_out) ); diff --git a/tb/tb_alu.v b/tb/tb_alu.v index 3abc655..f0f0b63 100644 --- a/tb/tb_alu.v +++ b/tb/tb_alu.v @@ -6,19 +6,19 @@ module tb_alu (); reg [31:0] in_a; reg [31:0] in_b; - reg [3:0] op_code; + reg [3:0] func; wire [31:0] out; alu alu ( .in_a(in_a), .in_b(in_b), - .op_code(op_code), + .func(func), .out(out) ); initial begin // ALU - add - op_code = ADD; + func = ADD; in_a = 32'b0; in_b = 32'b0; `assert("alu : 0 + 0", out, 0) @@ -42,7 +42,7 @@ module tb_alu (); `assert("alu : MIN_INT + -1", out, 32'b01111111111111111111111111111111) // ALU - sub - op_code = SUB; + func = SUB; in_a = 32'b0; in_b = 32'b0; `assert("alu : 0 - 0", out, 0) @@ -66,7 +66,7 @@ module tb_alu (); `assert("alu : MIN_INT - -1", out, 32'b10000000000000000000000000000001) // ALU - left shift - op_code = SLL; + func = SLL; in_a = 32'b1; in_b = 32'b1; `assert("alu : 1 << 1", out, 2) @@ -82,7 +82,7 @@ module tb_alu (); `assert("alu : 3 << 31", out, 32'b00000000000000000000000000000000) // ALU - less than - op_code = SLT; + func = SLT; in_a = 32'b0; in_b = 32'b0; `assert("alu : 0 < 0", out, 0) @@ -100,7 +100,7 @@ module tb_alu (); `assert("alu : MIN_INT << MIN_INT + 1", out, 1) // ALU - xor - op_code = XOR; + func = XOR; in_a = 32'b0; in_b = 32'b0; `assert("alu : 0 ^ 0", out, 32'b00000000000000000000000000000000) @@ -120,7 +120,7 @@ module tb_alu (); `assert("alu : 00000011001000010001000011000000 ^ 10101111001011101110111111111011", out, 32'b10101100000011111111111100111011) // ALU - right shift - op_code = SRL; + func = SRL; in_a = 32'b1; in_b = 32'b1; `assert("alu : 1 >> 1", out, 0) @@ -139,7 +139,7 @@ module tb_alu (); `assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001) // ALU - arithmetic right shift - op_code = SRA; + func = SRA; in_a = 32'b1; in_b = 32'b1; `assert("alu : 1 >>> 1", out, 0) @@ -158,7 +158,7 @@ module tb_alu (); `assert("alu : 1000..111 >>> 31", out, 32'b11111111111111111111111111111111) // ALU - or - op_code = OR; + func = OR; in_a = 32'b0; in_b = 32'b0; `assert("alu : 0 | 0", out, 32'b00000000000000000000000000000000) @@ -178,7 +178,7 @@ module tb_alu (); `assert("alu : 00000011001000010001000011000000 | 10101111001011101110111111111011", out, 32'b10101111001011111111111111111011) // ALU - and - op_code = AND; + func = AND; in_a = 32'b0; in_b = 32'b0; `assert("alu : 0 & 0", out, 32'b00000000000000000000000000000000) -- 2.30.2 From 7c1a871e99d70877fba527851d9c9a2edc1e0f39 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Tue, 24 Oct 2023 20:08:36 +0900 Subject: [PATCH 16/17] Add: tb registers bank --- tb/tb_mux4_1.v | 53 +++++++++++++++++++++++++++++ tb/tb_registers_bank.v | 75 ++++++++++++++++++++++++++++++++++++++++++ tb/tb_tools.vh | 2 +- 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 tb/tb_mux4_1.v create mode 100644 tb/tb_registers_bank.v diff --git a/tb/tb_mux4_1.v b/tb/tb_mux4_1.v new file mode 100644 index 0000000..078dd32 --- /dev/null +++ b/tb/tb_mux4_1.v @@ -0,0 +1,53 @@ +`timescale 1ns / 1ps +`include "tb_tools.vh" + +module tb_mux4_1 (); + + reg [1:0] sel; + reg [31:0] in_1; + reg [31:0] in_2; + reg [31:0] in_3; + reg [31:0] in_4; + wire [31:0] out; + + mux4_1 mux ( + .in_1(in_1), + .in_2(in_2), + .in_3(in_3), + .in_4(in_4), + .sel(sel), + .out(out) + ); + + initial begin + in_1 = 1'b0; + in_2 = 1'b0; + in_3 = 1'b0; + in_4 = 1'b0; + sel = 2'b00; + `assert("mux in_1: 0, in_2: 0, in_3: 0, in_4: 0, sel: 0", out, 0) + in_1 = 1'b1; + `assert("mux in_1: 1, in_2: 0, in_3: 0, in_4: 0, sel: 0", out, 1) + sel = 2'b01; + `assert("mux in_1: 1, in_2: 0, in_3: 0, in_4: 0, sel: 1", out, 0) + in_2 = 1'b1; + `assert("mux in_1: 1, in_2: 1, in_3: 0, in_4: 0, sel: 1", out, 1) + sel = 2'b10; + `assert("mux in_1: 1, in_2: 0, in_3: 0, in_4: 0, sel: 2", out, 0) + in_3 = 1'b1; + `assert("mux in_1: 1, in_2: 1, in_3: 1, in_4: 0, sel: 2", out, 1) + sel = 2'b11; + `assert("mux in_1: 1, in_2: 0, in_3: 1, in_4: 0, sel: 3", out, 0) + in_4 = 1'b1; + `assert("mux in_1: 1, in_2: 1, in_3: 1, in_4: 1, sel: 3", out, 1) + in_1 = 1'b0; + `assert("mux in_1: 0, in_2: 1, in_3: 1, in_4: 1, sel: 1", out, 1) + in_2 = 1'b0; + `assert("mux in_1: 0, in_2: 0, in_3: 1, in_4: 1, sel: 1", out, 1) + sel = 2'b00; + `assert("mux in_1: 0, in_2: 0, in_3: 1, in_4: 1, sel: 0", out, 0) + + `end_message + end + +endmodule : tb_mux4_1 diff --git a/tb/tb_registers_bank.v b/tb/tb_registers_bank.v new file mode 100644 index 0000000..599b27b --- /dev/null +++ b/tb/tb_registers_bank.v @@ -0,0 +1,75 @@ +`timescale 1ns / 1ps +`include "tb_tools.vh" + +module tb_registers_bank (); + reg clk; + reg reset; + integer i; + reg we; + reg [4:0] sel_in; + reg [4:0] sel_out_a; + reg [4:0] sel_out_b; + reg [31:0] data_in; + wire [31:0] data_out_a; + wire [31:0] data_out_b; + + registers_bank registers_bank ( + .clock(clk), + .reset(reset), + .we(we), + .sel_in(sel_in), + .sel_out_a(sel_out_a), + .sel_out_b(sel_out_b), + .data_in(data_in), + .data_out_a(data_out_a), + .data_out_b(data_out_b) + ); + + initial begin + reset = 1'b1; + #10 + reset = 1'b0; + end + + initial begin + clk = 1'b0; + for (i = 0; i < 100; i = i + 1) begin + #1 clk = ~clk; + end + end + + initial begin + + we = 1'b0; + sel_in = 5'b00000; + sel_out_a = 5'b00000; + sel_out_b = 5'b00000; + data_in = 32'b0; + `assert("registers_bank we: 0, sel_in: 0, sel_out_a: 0, sel_out_b: 0, data_in: 0", data_out_a, 0) + we = 1'b1; + data_in = 32'b1; + `assert("registers_bank we: 1, sel_in: 0, sel_out_a: 0, sel_out_b: 0, data_in: 1", data_out_a, 0) + sel_in = 5'b00001; + `assert("registers_bank we: 1, sel_in: 1, sel_out_a: 0, sel_out_b: 0, data_in: 1", data_out_a, 0) + sel_out_a = 5'b00001; + `assert("registers_bank we: 1, sel_in: 1, sel_out_a: 1, sel_out_b: 0, data_in: 1", data_out_a, 1) + `assert("registers_bank we: 1, sel_in: 1, sel_out_a: 1, sel_out_b: 0, data_in: 1", data_out_b, 0) + sel_out_b = 5'b00001; + `assert("registers_bank we: 1, sel_in: 1, sel_out_a: 1, sel_out_b: 1, data_in: 1", data_out_b, 1) + we = 1'b0; + data_in = 32'b11; + `assert("registers_bank we: 0, sel_in: 1, sel_out_a: 1, sel_out_b: 1, data_in: 3", data_out_a, 1) + `assert("registers_bank we: 0, sel_in: 1, sel_out_a: 1, sel_out_b: 1, data_in: 3", data_out_b, 1) + data_in = 32'b111; + sel_in = 5'b11111; + sel_out_a = 5'b11111; + we = 1'b1; + `assert("registers_bank we: 1, sel_in: 31, sel_out_a: 31, sel_out_b: 1, data_in: 7", data_out_a, 7) + `assert("registers_bank we: 1, sel_in: 31, sel_out_a: 31, sel_out_b: 1, data_in: 7", data_out_b, 1) + + `end_message + end + + + +endmodule : tb_registers_bank diff --git a/tb/tb_tools.vh b/tb/tb_tools.vh index d8774c8..ad0875c 100644 --- a/tb/tb_tools.vh +++ b/tb/tb_tools.vh @@ -1,5 +1,5 @@ `define assert(message, expected, got) \ - #20 \ + #4 \ if(expected !== got) begin \ $display("\033[0;31m[FAILED]\033[0m : %s - got: %d, expected: %d", message, expected, got); \ end -- 2.30.2 From 0fb4170797840d014f039583a9b3f49d39d8c072 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Tue, 24 Oct 2023 21:19:24 +0900 Subject: [PATCH 17/17] Add: tb_risc_v fibonacci compute --- rtl/instruction.v | 24 -------- tb/tb_risc_v_cpu.v | 147 +++++++++++++++++++++++++++++++++++++++++++-- tb/tb_tools.vh | 9 +++ 3 files changed, 151 insertions(+), 29 deletions(-) diff --git a/rtl/instruction.v b/rtl/instruction.v index 3968c54..bb76915 100644 --- a/rtl/instruction.v +++ b/rtl/instruction.v @@ -3,30 +3,6 @@ module instruction (input [31:0] address, reg [31:0] memory [63:0]; - // ADDi $1, R[0], R[6] - R[6] = 1 - // "000000000001_00000_000_00110_0010000" - assign memory[0] = 32'b00000000000100000000001100010000; - - // ADDi $0, R[0], R[7] - R[7] = 0 - // "000000000000_00000_000_00111_0010000" - assign memory[4] = 32'b00000000000000000000001110010000; - - // ADDi $0, R[6], R[8] - R[8] = R[6] - // "000000000000_00110_000_01000_0010000" - assign memory[8] = 32'b00000000000000110000010000010000; - - // ADD R[7], R[6], R[6] - R[6] = R[7] + R[6] - // "0000000_00111_00110_000_00110_0110000" - assign memory[12] = 32'b00000000011100110000001100110000; - - // ADDi $0, R[8], R[7] - R[7] = R[8] - // "000000000000_01000_000_00111_0010000" - assign memory[16] = 32'b00000000000001000000001110010000; - - // JUMP - // 11111111111111111101_00111_1101100 - assign memory[20] = 32'b11111111111111110100001011101100; - assign instruction = memory[address]; endmodule diff --git a/tb/tb_risc_v_cpu.v b/tb/tb_risc_v_cpu.v index f7d9988..0c0da1a 100644 --- a/tb/tb_risc_v_cpu.v +++ b/tb/tb_risc_v_cpu.v @@ -14,16 +14,153 @@ module tb_risc_v_cpu (); ); initial begin + /* Reset */ reset = 1'b1; #10 reset = 1'b0; - end - initial begin clk = 1'b0; - for (i = 0; i < 100; i = i + 1) begin - #1 clk = ~clk; - end + + /* Fibonacci */ + + /* ADDi $1, R[0], R[6] - R[6] = 1 */ + /* "000000000001_00000_000_00110_0010000" */ + risc_v_cpu.uut_instruction.memory[0] = 32'b00000000000100000000001100010000; + + /* ADDi $0, R[0], R[7] - R[7] = 0 */ + /* "000000000000_00000_000_00111_0010000" */ + risc_v_cpu.uut_instruction.memory[4] = 32'b00000000000000000000001110010000; + + /* ADDi $0, R[6], R[8] - R[8] = R[6] */ + /* "000000000000_00110_000_01000_0010000" */ + risc_v_cpu.uut_instruction.memory[8] = 32'b00000000000000110000010000010000; + + /* ADD R[7], R[6], R[6] - R[6] = R[7] + R[6] */ + /* "0000000_00111_00110_000_00110_0110000" */ + risc_v_cpu.uut_instruction.memory[12] = 32'b00000000011100110000001100110000; + + /* ADDi $0, R[8], R[7] - R[7] = R[8] */ + /* "000000000000_01000_000_00111_0010000" */ + risc_v_cpu.uut_instruction.memory[16] = 32'b00000000000001000000001110010000; + + /* JUMP - 12 */ + /* 11111111111111111101_00111_1101100 */ + risc_v_cpu.uut_instruction.memory[20] = 32'b11111111111111110100001011101100; + + `next_cycle + `assert_no_wait("FIBO INIT: ADDi $1, R[0], R[6] - R[6] = 1", risc_v_cpu.registers_bank.registers[6], 1) + `next_cycle + `assert_no_wait("FIBO INIT: ADDi $0, R[0], R[7] - R[7] = 0", risc_v_cpu.registers_bank.registers[7], 0) + `next_cycle + `assert_no_wait("FIBO CYCLE 1: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 1) + `next_cycle + `assert_no_wait("FIBO CYCLE 1: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 1) + `next_cycle + `assert_no_wait("FIBO CYCLE 1: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 1) + `next_cycle + `assert_no_wait("FIBO VALUE 1: 1", risc_v_cpu.registers_bank.registers[7], 1) + `assert_no_wait("FIBO CYCLE 1: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 2: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 1) + `next_cycle + `assert_no_wait("FIBO CYCLE 2: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 2) + `next_cycle + `assert_no_wait("FIBO CYCLE 2: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 1) + `next_cycle + `assert_no_wait("FIBO VALUE 2: 1", risc_v_cpu.registers_bank.registers[7], 1) + `assert_no_wait("FIBO CYCLE 2: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 3: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 2) + `next_cycle + `assert_no_wait("FIBO CYCLE 3: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 3) + `next_cycle + `assert_no_wait("FIBO CYCLE 3: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 2) + `next_cycle + `assert_no_wait("FIBO VALUE 3: 2", risc_v_cpu.registers_bank.registers[7], 2) + `assert_no_wait("FIBO CYCLE 3: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 4: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 3) + `next_cycle + `assert_no_wait("FIBO CYCLE 4: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 5) + `next_cycle + `assert_no_wait("FIBO CYCLE 4: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 3) + `next_cycle + `assert_no_wait("FIBO VALUE 4: 3", risc_v_cpu.registers_bank.registers[7], 3) + `assert_no_wait("FIBO CYCLE 4: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 5: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 5) + `next_cycle + `assert_no_wait("FIBO CYCLE 5: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 5: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 5) + `next_cycle + `assert_no_wait("FIBO VALUE 5: 5", risc_v_cpu.registers_bank.registers[7], 5) + `assert_no_wait("FIBO CYCLE 5: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 6: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 6: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 13) + `next_cycle + `assert_no_wait("FIBO CYCLE 6: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 8) + `next_cycle + `assert_no_wait("FIBO VALUE 6: 8", risc_v_cpu.registers_bank.registers[7], 8) + `assert_no_wait("FIBO CYCLE 6: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 7: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 13) + `next_cycle + `assert_no_wait("FIBO CYCLE 7: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 21) + `next_cycle + `assert_no_wait("FIBO CYCLE 7: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 13) + `next_cycle + `assert_no_wait("FIBO VALUE 7: 13", risc_v_cpu.registers_bank.registers[7], 13) + `assert_no_wait("FIBO CYCLE 7: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 8: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 21) + `next_cycle + `assert_no_wait("FIBO CYCLE 8: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 34) + `next_cycle + `assert_no_wait("FIBO CYCLE 8: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 21) + `next_cycle + `assert_no_wait("FIBO VALUE 8: 21", risc_v_cpu.registers_bank.registers[7], 21) + `assert_no_wait("FIBO CYCLE 8: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 9: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 34) + `next_cycle + `assert_no_wait("FIBO CYCLE 9: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 55) + `next_cycle + `assert_no_wait("FIBO CYCLE 9: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 34) + `next_cycle + `assert_no_wait("FIBO VALUE 9: 34", risc_v_cpu.registers_bank.registers[7], 34) + `assert_no_wait("FIBO CYCLE 9: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 10: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 55) + `next_cycle + `assert_no_wait("FIBO CYCLE 10: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 89) + `next_cycle + `assert_no_wait("FIBO CYCLE 10: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 55) + `next_cycle + `assert_no_wait("FIBO VALUE 10: 55", risc_v_cpu.registers_bank.registers[7], 55) + `assert_no_wait("FIBO CYCLE 10: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 11: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 89) + `next_cycle + `assert_no_wait("FIBO CYCLE 11: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 144) + `next_cycle + `assert_no_wait("FIBO CYCLE 11: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 89) + `next_cycle + `assert_no_wait("FIBO VALUE 11: 89", risc_v_cpu.registers_bank.registers[7], 89) + `assert_no_wait("FIBO CYCLE 11: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + `next_cycle + `assert_no_wait("FIBO CYCLE 12: ADDi $0, R[6], R[8] - R[8] = R[6]", risc_v_cpu.registers_bank.registers[8], 144) + `next_cycle + `assert_no_wait("FIBO CYCLE 12: ADD R[7], R[6], R[6] - R[6] = R[7] + R[6]", risc_v_cpu.registers_bank.registers[6], 233) + `next_cycle + `assert_no_wait("FIBO CYCLE 12: ADDi $0, R[8], R[7] - R[7] = R[8]", risc_v_cpu.registers_bank.registers[7], 144) + `next_cycle + `assert_no_wait("FIBO VALUE 12: 144", risc_v_cpu.registers_bank.registers[7], 144) + `assert_no_wait("FIBO CYCLE 12: JUMP - 12", risc_v_cpu.program_counter.pc_addr, 8) + + `end_message end endmodule : tb_risc_v_cpu diff --git a/tb/tb_tools.vh b/tb/tb_tools.vh index ad0875c..5c39e75 100644 --- a/tb/tb_tools.vh +++ b/tb/tb_tools.vh @@ -4,4 +4,13 @@ $display("\033[0;31m[FAILED]\033[0m : %s - got: %d, expected: %d", message, expected, got); \ end +`define assert_no_wait(message, expected, got) \ + if(expected !== got) begin \ + $display("\033[0;31m[FAILED]\033[0m : %s - got: %d, expected: %d", message, expected, got); \ + end + `define end_message $display("\033[0;32mIf no \033[0m[FAILED]\033[0;32m messages, all tests passed!\033[0m"); + +`define next_cycle \ + #1 clk = ~clk; \ + #1 clk = ~clk; \ No newline at end of file -- 2.30.2