diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..75711b5 Binary files /dev/null and b/.DS_Store differ diff --git a/Readme2.md b/Readme2.md new file mode 100644 index 0000000..d42f77e --- /dev/null +++ b/Readme2.md @@ -0,0 +1 @@ +#Hello World \ No newline at end of file diff --git a/repo/.DS_Store b/repo/.DS_Store new file mode 100644 index 0000000..6b38ab7 Binary files /dev/null and b/repo/.DS_Store differ diff --git a/repo/rtl/Reg_File.sv b/repo/rtl/Reg_File.sv new file mode 100644 index 0000000..5a52494 --- /dev/null +++ b/repo/rtl/Reg_File.sv @@ -0,0 +1,39 @@ +module Reg_File #( + input logic [4:0] AD1, + input logic [4:0] AD2, + input logic [4:0] AD3, + input logic WE3, + input logic [31:0] WD3, + input logic clk, + + output logic [31:0] RD1, + output logic [31:0] RD2, + output logic [31:0] a0 +); + +logic [31:0] rf[32]; // 32 registers of 32 bits each + +//Ensures that all the registers are 0 at the start of simulation +initial begin + for (int i = 0; i < 32; i++) begin + rf[i] = 32'b0; + end +end + + +always_ff @(posedge clk) begin + if (WE3) begin + //If write is high, write the data + if (AD3 != 5'b0) begin + rf[AD3] <= WD3; // Register 0 is hardwired to 0, block all writes + end + end +end + +assign RD1 = rf[AD1]; // Read data from register AD1 + +assign RD2 = rf[AD2]; // Read data from register AD2 + +assign a0 = rf[10]; // Output the value of register x10 (a0), hardwired to adress 10 (register a0) + +endmodule \ No newline at end of file diff --git a/repo/rtl/alu.sv b/repo/rtl/alu.sv new file mode 100644 index 0000000..b2792e8 --- /dev/null +++ b/repo/rtl/alu.sv @@ -0,0 +1,22 @@ +module alu ( + input logic [31:0] a, + input logic [31:0] b, + input logic ALUCtrl, // 1 -> a+b, 0 -> a-b (or compare) + output logic [31:0] result, + output logic not_equal // (a != b) +); + logic [31:0] sum, diff; + + assign sum = a + b; + assign diff = a - b; + + assign not_equal = (a != b); + + always_comb begin + if (ALUAdd) + result = sum; + else + result = diff; // used only for subtraction/comparison + end + +endmodule diff --git a/repo/rtl/control_unit.sv b/repo/rtl/control_unit.sv new file mode 100644 index 0000000..5fc36b6 --- /dev/null +++ b/repo/rtl/control_unit.sv @@ -0,0 +1,62 @@ +// control_unit.sv +// - ADDI (I-type) +// - BNE (B-type branch) + +module control_unit ( + input logic [6:0] opcode, // instr[6:0] + input logic [2:0] funct3, // instr[14:12] + output logic RegWrite, // write to rd? + output logic ALUSrc, // 1: use immediate, 0: use rs2 + output logic Branch, // is this a branch? + output logic IsBType, // 1: use B-type immediate, 0: I-type + output logic ALUAdd, // 1: ALU does add, 0: ALU does sub/compare + output logic CompareNotEqual // 1: branch on not equal (BNE) +); + + // RISC-V opcode constants + localparam OPCODE_OP_IMM = 7'b0010011; // I-type arithmetic (ADDI) + localparam OPCODE_BRANCH = 7'b1100011; // B-type branches (BNE, BEQ, etc) + + always_comb begin + RegWrite = 1'b0; + ALUSrc = 1'b0; + Branch = 1'b0; + IsBType = 1'b0; + ALUAdd = 1'b1; // default to ADD + CompareNotEqual = 1'b0; + + + unique case (opcode) + // ================================ + // I-TYPE: ADDI + // ================================ + OPCODE_OP_IMM: begin + // ADDI rd, rs1, imm + RegWrite = 1'b1; // write result to rd + ALUSrc = 1'b1; // second ALU operand is immediate + Branch = 1'b0; // not a branch + IsBType = 1'b0; // use I-type immediate + ALUAdd = 1'b1; // ALU does add + CompareNotEqual = 1'b0; // not used + end + + // ================================ + // B-TYPE: BNE + // ================================ + OPCODE_BRANCH: begin + // We only care about BNE here: + // funct3 = 3'b001 => BNE + Branch = 1'b1; // this is a branch + IsBType = 1'b1; // use B-type immediate format + ALUSrc = 1'b0; // compare rs1 and rs2 + RegWrite = 1'b0; // branches don't write rd + ALUAdd = 1'b0; // ALU can be used as subtract/compare + CompareNotEqual = (funct3 == 3'b001); // 1 for BNE + end + + default: begin + end + endcase + end + +endmodule diff --git a/repo/rtl/imm_gen.sv b/repo/rtl/imm_gen.sv new file mode 100644 index 0000000..5d86c1a --- /dev/null +++ b/repo/rtl/imm_gen.sv @@ -0,0 +1,31 @@ +module imm_gen ( + input logic [31:0] instr, + input logic is_b_type, // 1 for branch, 0 for I-type + output logic [31:0] imm +); + logic [31:0] imm_i; + logic [31:0] imm_b; + logic [12:0] imm_b_raw; + + // I-type immediate (addi) + assign imm_i = {{20{instr[31]}}, instr[31:20]}; + + // B-type immediate (bne) + // imm[12|10:5|4:1|11|0], with bit 0 = 0 + assign imm_b_raw = { + instr[31], // imm[12] + instr[7], // imm[11] + instr[30:25], // imm[10:5] + instr[11:8], // imm[4:1] + 1'b0 // imm[0] + }; + assign imm_b = {{19{imm_b_raw[12]}}, imm_b_raw}; + + always_comb begin + if (is_b_type) + imm = imm_b; + else + imm = imm_i; + end + +endmodule diff --git a/repo/rtl/pc_reg.sv b/repo/rtl/pc_reg.sv new file mode 100644 index 0000000..95787e5 --- /dev/null +++ b/repo/rtl/pc_reg.sv @@ -0,0 +1,13 @@ +module pc_reg ( + input logic clk, + input logic rst, + input logic [31:0] pc_next, + output logic [31:0] pc +); + always_ff @(posedge clk or posedge rst) begin + if (rst) + pc <= 32'h0000_0000; // start at address 0 + else + pc <= pc_next; + end +endmodule diff --git a/repo/rtl/ram.sv b/repo/rtl/ram.sv new file mode 100644 index 0000000..38d23d8 --- /dev/null +++ b/repo/rtl/ram.sv @@ -0,0 +1,19 @@ +// Asynchronous 32-bit instruction RAM for RISC-V program memory + +module ram #( + parameter ADDR_WIDTH = 8, // number of instruction addresses + DATA_WIDTH = 32 // 32-bit RISC-V instructions +)( + input logic [ADDR_WIDTH-1:0] addr, // word address (PC[...:2]) + output logic [DATA_WIDTH-1:0] dout // instruction +); + + // RAM array: 2^ADDR_WIDTH entries of 32 bits + logic [DATA_WIDTH-1:0] ram_array [0:(2**ADDR_WIDTH)-1]; + + + // Asynchronous read: output changes as soon as addr changes + always_comb begin + dout = ram_array[addr]; + end +endmodule diff --git a/repo/rtl/top_ALU.sv b/repo/rtl/top_ALU.sv new file mode 100644 index 0000000..a35edb1 --- /dev/null +++ b/repo/rtl/top_ALU.sv @@ -0,0 +1,54 @@ +// This module "wraps" the Register File, the MUX, and the ALU +// as shown in the brown box in your diagram. +module top_ALU ( + // --- Inputs to the Block --- + input logic clk, // Clock for Reg File + input logic [4:0] AD1, // Read Address 1 (rs1) + input logic [4:0] AD2, // Read Address 2 (rs2) + input logic [4:0] AD3, // Write Address (rd) + input logic WE3, // Reg Write Enable + input logic ALUSrc, // MUX select signal + input logic ALUCtrl, // ALU control (Add/Sub) + input logic [31:0] ImmOp, // Immediate data from Sign Extend + + // --- Outputs from the Block --- + output logic EQ, // EQ flag to Control Unit + output logic [31:0] a0 // Special output for testing +); + + // --- 1. INTERNAL WIRES --- + logic [31:0] w_RD1; + logic [31:0] w_RD2; + logic [31:0] w_ALUOut; + logic [31:0] w_ALUop2; + + + // --- 2. COMPONENT INSTANCES --- + + Reg_File rf_inst ( + .clk(clk), + .AD1(AD1), + .AD2(AD2), + .AD3(AD3), + .WE3(WE3), + .WD3(w_ALUOut), + .RD1(w_RD1), + .RD2(w_RD2), + .a0(a0) + ); + + + alu alu_inst ( + .a(w_RD1), + .b(w_ALUop2), + .ALUCtrl(ALUCtrl), + .result(w_ALUOut), + .EQ(EQ) + ); + + + // --- 3. MUX LOGIC --- + assign w_ALUop2 = (ALUSrc) ? ImmOp : w_RD2; + + +endmodule \ No newline at end of file diff --git a/repo/tb/doit.sh b/repo/tb/doit.sh index 2a3561b..661e3d6 100755 --- a/repo/tb/doit.sh +++ b/repo/tb/doit.sh @@ -38,6 +38,17 @@ for file in "${files[@]}"; do name="top" fi + # Automatically detect latest GoogleTest installation under Homebrew + GTEST_BASE=$(brew --prefix googletest 2>/dev/null) + if [ -z "$GTEST_BASE" ]; then + echo "${RED}Error: GoogleTest not found via Homebrew.${RESET}" + exit 1 + fi + + # Construct include and lib paths dynamically + GTEST_INCLUDE="$GTEST_BASE/include" + GTEST_LIB="$GTEST_BASE/lib" + # Translate Verilog -> C++ including testbench verilator -Wall --trace \ -cc ${RTL_FOLDER}/${name}.sv \ @@ -45,8 +56,8 @@ for file in "${files[@]}"; do -y ${RTL_FOLDER} \ --prefix "Vdut" \ -o Vdut \ - -CFLAGS "-isystem /opt/homebrew/Cellar/googletest/1.15.2/include"\ - -LDFLAGS "-L/opt/homebrew/Cellar/googletest/1.15.2/lib -lgtest -lgtest_main -lpthread" \ + -CFLAGS "-std=c++17 -isystem ${GTEST_INCLUDE}" \ + -LDFLAGS "-L${GTEST_LIB} -lgtest -lgtest_main -lpthread" # Build C++ project with automatically generated Makefile make -j -C obj_dir/ -f Vdut.mk @@ -71,4 +82,4 @@ else total=$((passes + fails)) echo "${RED}Failure! Only ${passes} test(s) passed out of ${total}." exit 1 -fi +fi \ No newline at end of file