From 0dbc9fbc97956f20818d5425bc490640199ada3b Mon Sep 17 00:00:00 2001 From: ambre622 Date: Thu, 13 Nov 2025 10:45:59 +0000 Subject: [PATCH] alu, sign extension, control unit --- .DS_Store | Bin 0 -> 6148 bytes repo/.DS_Store | Bin 0 -> 6148 bytes repo/rtl/alu.sv | 22 ++++++++++++++ repo/rtl/control_unit.sv | 62 +++++++++++++++++++++++++++++++++++++++ repo/rtl/imm_gen.sv | 31 ++++++++++++++++++++ repo/rtl/pc_reg.sv | 13 ++++++++ repo/rtl/ram.sv | 19 ++++++++++++ 7 files changed, 147 insertions(+) create mode 100644 .DS_Store create mode 100644 repo/.DS_Store create mode 100644 repo/rtl/alu.sv create mode 100644 repo/rtl/control_unit.sv create mode 100644 repo/rtl/imm_gen.sv create mode 100644 repo/rtl/pc_reg.sv create mode 100644 repo/rtl/ram.sv diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..75711b59b9b5e8abf4bce43925be236bd40489bb GIT binary patch literal 6148 zcmeHK%}T>S5Z<-XM2e7uLXQEj1>0H+;w8lT0!H+pQWFw17_%iw&7l->))(?gd>&_Z zH)63~MeGdhe)GGV{UH0p7~|e7>N93D#w=)v9F-MB$jTte;#?LaQ4A?JS4kF$$`i9JDrBv%0@k)=P3+EmJ{a}7&SC#((RJp>1JH+~ z;bLJ~d;13`=aa|uDHAV>P!4=c+0od*D=44qdG_-x71=%bn*1h@kQg8ahyh|?eHqYa zg4JGM3TWlT05R|b1Gqmp&=6gXwL-adK!?|7j2nn3pyOKt(b4E?tQA58gsW0ORm$}f zgR64zJ37zRSSwWJjLVr}96fXMc;Rw(@H;Y{aaSSr!~ij{%s@+-HlF`y@XM@xnk>p;7MhJtxDDj=XQT>`+seWW9UD(;{Td9KDS5Z<-bM2e7uLXQhx3%0cu#7l_v1&ruHr6#0kFlI}VnnNk%tS{t~_&m<+ zZop#BB6bFLzxmzGevtiPjB#%f4H$D6V>UEIj!J`|yD_w7k`XzMkq^Qbto0zgj%Vf6 z**}+Q5ya^%Qw4D}gOt0QIE`fK$weCFs@B&5d)Kz7PItK+j{7}vJUChP#PW0q`e-~_ zt!(??@aXJv`kcI^@=eppfo&yw25Wc+#jNJl&(cJukKn1Z>nuWIfEXYKh=I*!z?=(q zXR~Rb)e{56Km!A~KL}`uuE9#9+B%@a>odmNh$x`rTLMuSbPZM-Ap*j6DWERp=83^| zIrxRia}8D+bvff|W*EoJTt8m8njQQ?r8Dkoq@EZc2G$v9Y16^;{{nuQ#z+2o30cGd zG4RhA;O&V&@nBKrZ2hr3JZlBC2WTjmSD^v|`r0J`4BSV$DyZWEb;xrKRvK{>^s90} Ox(Fyjs3Qh`fq^d%S4ocm literal 0 HcmV?d00001 diff --git a/repo/rtl/alu.sv b/repo/rtl/alu.sv new file mode 100644 index 0000000..79531bf --- /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 ALUAdd, // 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