initial module setup and declaration

This commit is contained in:
2026-09-19 23:34:01 -04:00
parent b71bc6a777
commit 7449625627
6 changed files with 369 additions and 33 deletions
+155
View File
@@ -0,0 +1,155 @@
module main_decoder (
input logic [6:0] opcode_i,
output logic branch_o, // branch or not
output logic result_src_o, //
output logic mem_write_o, // write to data memory or not
output logic alu_src_o, // alu use rd2 or ext imm
output logic [1:0] imm_src_o, //
output logic reg_write_o, // write to register or not
output logic [1:0] alu_op_o, // operation for alu to perform
output logic instr_invld_o // invalid or unsupported instruction
);
always_comb begin
case (opcode_i)
// lw
7'b0000011: begin
reg_write_o = 1'b1;
imm_src_o = 2'b00;
alu_src_o = 1'b1;
mem_write_o = 1'b0;
result_src_o = 1'b1;
branch_o = 1'b0;
alu_op_o = 2'b00;
end
// sw
7'b0100011: begin
reg_write_o = 1'b0;
imm_src_o = 2'b01;
alu_src_o = 1'b1;
mem_write_o = 1'b1;
branch_o = 1'b0;
alu_op_o = 2'b00;
end
// R type (add, sub, sll, srl)
7'b0110011: begin
reg_write_o = 1'b1;
alu_src_o = 1'b0;
mem_write_o = 1'b0;
result_src_o = 1'b0;
branch_o = 1'b0;
alu_op_o = 2'b10;
end
// beq
7'b0110011: begin
reg_write_o = 1'b0;
imm_src_o = 2'b10;
alu_src_o = 1'b0;
mem_write_o = 1'b0;
branch_o = 1'b1;
alu_op_o = 2'b01;
end
// invalid or unsupported instruction
default: instr_invld_o = 1'b1;
endcase
end
endmodule
module alu_decoder (
input logic [6:0] opcode_i,
input logic [2:0] funct3_i,
input logic funct7_i,
input logic [1:0] alu_op_i,
output logic [1:0] alu_control_o,
output logic instr_invld_o // invalid or unsupported instruction
);
always_comb begin
case (alu_op_i)
// lw, sw (alu add)
2'b00: alu_control_o = 2'b00;
// beq (alu sub)
2'b01: alu_control_o = 2'b01;
// R type
2'b10: begin
case (funct3_i)
// add, sub
3'b000: begin
case ({
opcode_i[5], funct7_i
})
// sub
2'b11: alu_control_o = 2'b01;
// add (00, 01, 10 cases)
default: alu_control_o = 2'b00;
endcase
end
// sll
3'b001: begin
alu_control = 2'b10;
end
// srl
3'b101: begin
alu_control = 2'b11;
end
default: instr_invld_o = 1'b1;
endcase
end
default: instr_invld_o = 1'b1;
endcase
end
endmodule
module control_unit (
input logic [31:0] instr_i,
input logic zero_flag_i,
output logic pc_src_o,
output logic result_src_o,
output logic mem_write_o,
output logic alu_src_o,
output logic [1:0] imm_src_o,
output logic reg_write_o,
output logic [1:0] alu_control_o,
output logic instr_invld_o
);
logic [6:0] opcode = instr_i[6:0];
logic [2:0] funct3 = instr_i[14:12];
logic funct7 = instr_i[30];
logic [1:0] alu_op;
logic instr_invld_md;
logic instr_invld_ad;
main_decoder md (
.opcode_i(opcode),
.branch_o(branch_o),
.result_src_o(result_src_o),
.alu_src_o(alu_src_o),
.imm_src_o(imm_src_o),
.reg_write_o(reg_write_o),
.mem_write_o(mem_write_o),
.alu_op_o(alu_op),
.instr_invld_o(instr_invld_md)
);
alu_decoder ad (
.opcode_i(opcode),
.funct3_i(funct3),
.funct7_i(funct7),
.alu_op_i(alu_op),
.alu_control_o(alu_control_o),
.instr_invld_o(instr_invld_ad)
);
always_comb begin
pc_src_o = zero_flag_i & branch_o;
instr_invld_o = instr_invld_md | instr_invld_ad;
end
endmodule
+50 -1
View File
@@ -61,6 +61,17 @@ module cpu_top (
.branch_taken_i(branch_taken) .branch_taken_i(branch_taken)
); );
logic alu_zero;
logic result_src;
logic mem_write;
logic alu_src;
logic [1:0] alu_control;
logic [31:0] imm_ext;
logic [31:0] rs1_data;
logic [31:0] rs2_data;
logic instr_invld_decode;
logic [31:0] alu_result;
//tied off, do fix //tied off, do fix
assign branch_vld = 1'b0; assign branch_vld = 1'b0;
assign branch_trgt = '0; assign branch_trgt = '0;
@@ -80,9 +91,47 @@ module cpu_top (
// Disconnect this once you instantiate reg_file and connect reg_file's output to it instead // Disconnect this once you instantiate reg_file and connect reg_file's output to it instead
//assign reg_crossbar_o = '{default: '0}; //assign reg_crossbar_o = '{default: '0};
assign reg_crossbar_o = registers;
initial begin
for (int i = 0; i < 32; i++) begin
reg_crossbar_o[i] = reg_values_o[i];
end
end
// instantiate the other modules you make here// // instantiate the other modules you make here//
decode decode (
.clk_i(clk_i),
.rst_i(rst_i),
.instr_i(instr),
.instr_vld_i(instr_vld),
.alu_zero_i(alu_zero),
.rd_data_i(result),
.pc_src_o(),
.result_src_o(result_src),
.mem_write_o(dsram_write_en_o),
.alu_src_o(alu_src),
.alu_control_o(alu_control),
.imm_ext_o(imm_ext),
.rs1_data_o(rs1_data),
.rs2_data_o(rs2_data),
.instr_invld_o(instr_invld_decode)
);
execute execute (
.clk_i(clk_i),
.alu_src_i(alu_src),
.imm_ext_i(imm_ext),
.alu_control_i(alu_control),
.current_pc_i(current_pc),
.rs1_data_i(rs1_data),
.rs2_data_i(rs2_data),
.alu_zero_o(alu_zero),
.alu_result_o(alu_result),
.pc_target_o()
);
assign dsram_addr_o = alu_result[9:0];
logic [31:0] result = result_src ? dsram_rdata_i : alu_result;
endmodule endmodule
+59
View File
@@ -0,0 +1,59 @@
module decode (
input logic clk_i,
input logic rst_i,
input logic [31:0] instr_i, // instruction to decode
input logic instr_vld_i, // is instruction passed valid
input logic alu_zero_i,
input logic [31:0] rd_data_i,
output logic pc_src_o,
output logic result_src_o,
output logic mem_write_o,
output logic alu_src_o,
output logic [1:0] alu_control_o,
output logic [31:0] imm_ext_o,
output logic [31:0] rs1_data_o,
output logic [31:0] rs2_data_o,
output logic instr_invld_o
);
logic [1:0] imm_src;
logic reg_write;
logic cu_invld;
logic se_invld;
assign instr_invld_o = ~instr_vld_i | cu_invld | se_invld; // instruction is invalid if provided invalid or decoded invalid
control_unit cu (
.instr_i(instr_i),
.zero_flag_i(alu_zero_i),
.pc_src_o(pc_src_o),
.result_src_o(result_src_o),
.mem_write_o(mem_write_o),
.alu_src_o(alu_src_o),
.imm_src_o(imm_src),
.reg_write_o(reg_write),
.alu_control_o(alu_control_o),
.instr_invld_o(cu_invld)
);
reg_file rf (
.clk_i(clk_i),
.rst_i(rst_i),
.rs1_addr_i(instr_i[19:15]),
.rs2_addr_i(instr_i[24:20]),
.rs1_data_o(rs1_data_o),
.rs2_data_o(rs2_data_o),
.rd_write_en_i(reg_write),
.rd_addr_i(instr_i[11:7]),
.rd_data_i(rd_data_i)
);
sign_extend se (
.instr_i(instr_i),
.imm_src_i(imm_src),
.imm_ext_o(imm_ext_o),
.instr_invld_o(se_invld)
);
endmodule
+55
View File
@@ -0,0 +1,55 @@
module alu (
input logic [31:0] a_i,
input logic [31:0] b_i,
input logic [ 1:0] alu_control_i,
output logic alu_zero_o,
output logic [31:0] alu_result_o
);
logic [31:0] result;
always_comb begin
unique case (alu_control_i)
// add
2'b00: result = a + b;
// sub
2'b01: result = a - b;
// sll
2'b10: result = a << b;
// srl
2'b11: result = a >> b;
endcase
assign alu_zero_o = (result == 1'b0);
end
endmodule
module execute (
input logic clk_i,
input logic alu_src_i,
input logic [31:0] imm_ext_i,
input logic [1:0] alu_control_i,
input logic [31:0] current_pc_i,
input logic [31:0] rs1_data_i,
input logic [31:0] rs2_data_i,
output logic alu_zero_o,
output logic [31:0] alu_result_o,
output logic [31:0] pc_target_o
);
logic [31:0] a = rs1_data;
logic [31:0] b = alu_src_i ? imm_ext_i : rs2_data;
assign pc_target_o = current_pc_i + imm_ext_i;
alu alu (
.a_i(a),
.b_i(b),
.alu_control_i(alu_control_i),
.alu_zero_o(alu_zero_o),
.alu_result_o(alu_result_o)
);
endmodule
+18
View File
@@ -0,0 +1,18 @@
module sign_extend (
input logic [31:0] instr_i,
input logic [ 1:0] imm_src_i,
output logic [31:0] imm_ext_o,
output logic instr_invld_o
);
always_comb begin
case (imm_src_i)
2'b00: imm_ext_o = {{20{instr_i[31]}}, instr_i[31:20]};
2'b01: imm_ext_o = {{20{instr_i[31]}}, instr_i[31:25], instr[11:7]};
2'b10: imm_ext_o = {{20{instr_i[31]}}, instr_i[7], instr[30:25], instr_i[11:8], 1'b0};
default: instr_invld_o = 1'b1;
endcase
end
endmodule
+32 -32
View File
@@ -4,46 +4,46 @@
//DO NOT MODIFY// //DO NOT MODIFY//
module sram_wrapper ( module sram_wrapper (
input logic clk_i, input logic clk_i,
input logic rst_i, input logic rst_i,
input logic en_i, input logic en_i,
input logic write_en_i, input logic write_en_i,
input logic [9:0] addr_i, input logic [ 9:0] addr_i,
input logic [31:0] wdata_i, input logic [31:0] wdata_i,
output logic [31:0] rdata_o, output logic [31:0] rdata_o,
output logic rready_o output logic rready_o
); );
CF_SRAM_1024x32_macro u_sram ( CF_SRAM_1024x32_macro u_sram (
.DO (rdata_o), .DO (rdata_o),
.DI (wdata_i), .DI (wdata_i),
.AD (addr_i), .AD (addr_i),
.CLKin (clk_i), .CLKin (clk_i),
.EN (en_i), .EN (en_i),
.R_WB (~write_en_i), .R_WB (~write_en_i),
.BEN (32'hFFFF_FFFF), .BEN (32'hFFFF_FFFF),
.TM (1'b0), .TM (1'b0),
.SM (1'b0), .SM (1'b0),
.WLBI (1'b0), .WLBI (1'b0),
.WLOFF (1'b0), .WLOFF (1'b0),
.ScanInCC (1'b0), .ScanInCC (1'b0),
.ScanInDL (1'b0), .ScanInDL (1'b0),
.ScanInDR (1'b0), .ScanInDR (1'b0),
.ScanOutCC (), .ScanOutCC(),
.vpwrac (1'b1), .vpwrac (1'b1),
.vpwrpc (1'b1) .vpwrpc (1'b1)
); );
logic rdata_valid;
always_ff @(posedge clk_i) begin logic rdata_valid;
if(rst_i) begin
rdata_valid <= 1'b0;
end else begin
rdata_valid <= en_i;
end
end
assign rready_o = rdata_valid; always_ff @(posedge clk_i) begin
if (rst_i) begin
rdata_valid <= 1'b0;
end else begin
rdata_valid <= en_i;
end
end
assign rready_o = rdata_valid;
endmodule endmodule