Initial commit

This commit is contained in:
Jose
2026-02-20 11:33:05 +01:00
parent fcdfb29c39
commit 8f2b31259c
9 changed files with 773 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: alu
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module alu(
input [31:0] A, B,
input [3:0] sel,
output reg [31:0] R,
output zero
);
always @(*) begin
case(sel)
4'b0000: R <= A + B; // add
4'b0001: R <= A - B; // sub
4'b0010: R <= A & B; // and
4'b0011: R <= A | B; // or
4'b0100: R <= A ^ B; // xor
4'b0101: R <= A << B[4:0]; // sll (shamt = 5 bits)
4'b0110: R <= A >> B[4:0]; // srl (logical)
4'b0111: R <= ($signed(A) < $signed(B)) ? 1 : 0; // slt signed
4'b1000: R <= (A < B) ? 1 : 0; // sltu unsigned
4'b1001: R <= $signed(A) >>> B[4:0]; // sra arithmetic right
4'b1010: R <= 32'b0; // default / nop opcional
default: R <= 32'b0;
endcase
end
assign zero = (R == 0);
endmodule

View File

@@ -0,0 +1,114 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: control
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module control(
input [6:0] opcode,
input [2:0] funct3,
input [6:0] funct7,
output reg we_reg,
output reg we_mem,
output reg mem_to_reg,
output reg alu_src,
output reg [3:0] alu_op,
output reg branch
);
localparam OP_R = 7'b0110011;
localparam OP_I = 7'b0010011;
localparam OP_LOAD= 7'b0000011;
localparam OP_STORE=7'b0100011;
localparam OP_BRANCH=7'b1100011;
localparam OP_JAL = 7'b1101111;
always @(*) begin
we_reg = 0;
we_mem = 0;
mem_to_reg = 0;
alu_src = 0;
alu_op = 4'b0000;
branch = 0;
case(opcode)
OP_R: begin
we_reg = 1;
alu_src = 0;
case({funct7,funct3})
10'b0000000000: alu_op = 4'b0000; // ADD
10'b0100000000: alu_op = 4'b0001; // SUB
10'b0000000111: alu_op = 4'b0010; // AND
10'b0000000110: alu_op = 4'b0011; // OR
10'b0000000100: alu_op = 4'b0100; // XOR
10'b0000000001: alu_op = 4'b0101; // SLL
10'b0000000101: alu_op = 4'b0110; // SRL
10'b0100000101: alu_op = 4'b0111; // SRA
10'b0000000010: alu_op = 4'b1000; // SLT
10'b0000000011: alu_op = 4'b1001; // SLTU
endcase
end
OP_I: begin
we_reg = 1;
alu_src = 1;
case(funct3)
3'b000: alu_op = 4'b0000; // ADDI
3'b111: alu_op = 4'b0010; // ANDI
3'b110: alu_op = 4'b0011; // ORI
3'b100: alu_op = 4'b0100; // XORI
3'b001: alu_op = 4'b0101; // SLLI
3'b101: alu_op = (funct7==7'b0000000)?4'b0110:4'b0111; // SRLI/SRAI
3'b010: alu_op = 4'b1000; // SLTI
3'b011: alu_op = 4'b1001; // SLTIU
endcase
end
OP_LOAD: begin
we_reg = 1;
we_mem = 0;
mem_to_reg = 1;
alu_src = 1; // addr = rs1 + immediate
alu_op = 4'b0000;
end
OP_STORE: begin
we_mem = 1;
alu_src = 1; // addr = rs1 + immediate
alu_op = 4'b0000;
end
OP_BRANCH: begin
branch = 1;
alu_src = 0;
alu_op = 4'b0001;
end
OP_JAL: begin
we_reg = 1; // rd <- PC+4
alu_src = 1;
alu_op = 4'b0000;
end
default: begin end
endcase
end
endmodule

View File

@@ -0,0 +1,40 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: dmem
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module dmem(
input clk,
input we,
input [31:0] address,
input [31:0] write_data,
output [31:0] read_data
);
reg [31:0] memory[0:255];
always @(posedge clk) begin
if (we)
memory[address[9:2]] <= write_data;
end
assign read_data = memory[address[9:2]];
endmodule

View File

@@ -0,0 +1,40 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: imem
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module imem(
input clk,
input [31:0] address,
input we,
input [31:0] write_data,
input [7:0] write_addr,
output [31:0] instruction
);
reg [31:0] memory[0:255];
always @(posedge clk) begin
if(we)
memory[write_addr] <= write_data;
end
assign instruction = memory[address[9:2]];
endmodule

View File

@@ -0,0 +1,40 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: imm_gen
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module imm_gen(
input [31:0] instr,
output reg [31:0] imm_out
);
always @(*) begin
case(instr[6:0])
7'b0010011,
7'b0000011:
imm_out = {{20{instr[31]}}, instr[31:20]};
7'b1101111:
imm_out = {{11{instr[31]}}, instr[31], instr[19:12], instr[20], instr[30:21], 1'b0};
default:
imm_out = 32'b0;
endcase
end
endmodule

View File

@@ -0,0 +1,34 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: pc
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module pc(
input clk, rst,
input [31:0] next_pc,
output reg [31:0] imem_addr
);
always @(posedge clk or posedge rst) begin
if (rst) imem_addr <= 0;
else imem_addr <= next_pc;
end
endmodule

View File

@@ -0,0 +1,39 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: regfile
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module regfile(
input clk, regwrite,
input [4:0] rs1, rs2, rd,
input [31:0] write_data,
output [31:0] read_data_1, read_data_2
);
reg [31:0] regs[0:31];
assign read_data_1 = (rs1 == 0) ? 0 : regs[rs1];
assign read_data_2 = (rs2 == 0) ? 0 : regs[rs2];
always @(posedge clk) begin
if (regwrite && rd != 0) regs[rd] <= write_data;
end
endmodule

View File

@@ -0,0 +1,135 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02/20/2026 09:21:52 AM
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module top(
input clk, rst,
input [31:0] uart_data,
output [31:0] pc_out, alu_out, mem_data
);
// = PC ===================================
wire [31:0] pc_next, pc;
wire branch_taken;
pc pc_inst(
.clk(clk),
.rst(rst),
.next_pc(pc_next),
.imem_addr(pc_curr)
);
assign pc_out = pc_curr;
// ========================================
// = IMEM =================================
wire [31:0] instr;
imem imem_inst(
.address(pc_curr),
.instruction(instr)
);
// ========================================
// = DECODE ===============================
wire [6:0] opcode = instr[6:0];
wire [4:0] rd = instr[11:7];
wire [2:0] funct3 = instr[14:12];
wire [4:0] rs1 = instr[19:15];
wire [4:0] rs2 = instr[24:20];
wire [6:0] funct7 = instr[31:25];
// ========================================
// regfile mux
wire [31:0] reg_write_data;
assign reg_write_data = mem_to_reg ? dmem_read_data : alu_out;
// = REGFILE ===============================
wire [31:0] reg_r1, reg_r2;
wire we_reg;
regfile regfile_inst(
.clk(clk),
.regwrite(we_reg),
.rs1(rs1),
.rs2(rs2),
.rd(rd),
.write_data(reg_write_data),
.read_data_1(reg_r1),
.read_data_2(reg_r2)
);
// ========================================
// = IMMGEN ===============================
wire [31:0] imm_out;
imm_gen imm_gen_inst(
.instr(instr),
.imm_out(imm_out)
);
// ========================================
// = CONTROL ===============================
wire we_mem, mem_to_reg, alu_src;
wire [3:0] alu_op;
control control_inst(
.opcode(opcode),
.funct3(funct3),
.funct7(funct7),
.we_reg(we_reg),
.we_mem(we_mem),
.mem_to_reg(mem_to_reg),
.alu_src(alu_src),
.alu_op(alu_op),
.branch(branch_taken)
);
// ========================================
// = ALU ==================================
wire [31:0] alu_b = alu_src ? imm_out : reg_r2;
alu alu_inst(
.A(reg_r1),
.B(alu_b),
.sel(alu_op),
.R(alu_out)
);
// ========================================
// = DMEM =================================
wire [31:0] dmem_read_data;
dmem dmem_inst(
.clk(clk),
.we(we_mem),
.address(alu_out),
.write_data(reg_r2),
.read_data(dmem_read_data)
);
assign mem_data = dmem_read_data;
// ========================================
// PC increment
assign pc_next = branch_taken ? (pc_curr + imm_out) : (pc_curr + 4);
endmodule