riscv single cycle

This commit is contained in:
2025-08-20 04:55:26 +03:00
parent 12dcc9d232
commit 679282782b
7 changed files with 986 additions and 15 deletions

133
chapter4/RISCcore.v Normal file
View File

@@ -0,0 +1,133 @@
module RISCcore (
input rst,
input clk,
output reg [31:0] pc,
output reg [31:0] next_pc,
output wire [31:0] instr
);
//PC
always @(posedge clk) begin
if(rst) begin
pc <= 32'h0;
next_pc <= 32'h4;
end
else begin
next_pc <= taken_br ? br_tgt_pc : (pc + 32'h4);
pc <= next_pc;
end
end
//IMem
reg [31:0] imem [0:255];
initial begin
$readmemh("program.hex", imem);
end
assign instr = imem[pc[31:2]];
//Decoder
wire isUType = ((instr[6:0] == 7'b0110111) || (instr[6:0] == 7'b0010111));
wire isIType = ((instr[6:0] == 7'b0000011) || (instr[6:0] == 7'b0000111) || (instr[6:0] == 7'b0010011) || (instr[6:0] == 7'b0011011) || (instr [6:0] == 7'b1100111));
wire isRType = ((instr[6:0] == 7'b0101111) || (instr[6:0] == 7'b0110011) || (instr[6:0] == 7'b0111011) || (instr[6:0] == 7'b0110011));
wire isSType = ((instr[6:0] == 7'b0100011) || (instr[6:0] == 7'b0100111));
wire isBType = (instr[6:0] == 7'b1100011);
wire isJType = (instr[6:0] == 7'b1101111);
wire [4:0] rs1 = instr[19:15];
wire [4:0] rs2 = instr[24:20];
wire [4:0] rd = instr[11:7];
wire rs2Valid = (isRType || isSType || isBType);
wire rs1Valid = (~isUType && ~isJType);
wire rdValid = (~isSType && ~isBType);
wire [3:0] funct3 = instr[14:12];
wire [6:0] funct7 = instr[31:25];
wire funct3Valid = rs1Valid;
wire funct7Valid = isRType;
wire [31:0] Iimm = {{21{instr[31]}}, {instr[30:25]}, {instr[24:20]}};
wire [31:0] Simm = {{21{instr[31]}}, {instr[30:25]}, {instr[11:7]}};
wire [31:0] Bimm = {{20{instr[31]}}, {instr[7]}, {instr[30:25]}, {instr[11:8]}, 1'b0};
wire [31:0] Uimm = {{instr[31]}, {instr[30:20]}, {instr[19:12]}, {12{1'b0}};
wire [31:0] Jimm = {{12{instr[31]}}, {instr[19:12]}, {instr[20]}, {instr[30:25]}, {instr[24:21]}, 1'b0};
//Instructions
isBEQ = (funct3 == 3'b000 && isBType);
isBNE = (funct3 == 3'b001 && isBType);
isBLT = (funct3 == 3'b100 && isBType);
isBGE = (funct3 == 3'b101 && isBType);
isBLTU = (funct3 == 3'b110 && isBType);
isBGEU = (funct3 == 3'b111 && isBType);
isADDI = (funct3 == 3'b000 && isIType);
isADD = (funct7[5] == 1'b0 && isRType);
isLW = (funct3 == 3'b010 && isIType);
isSW = (funct3 == 3'b010 && isSType);
//Register file
wire rf_wr_en;
wire [4:0] rf_wr_index;
wire [31:0] rf_wr_data;
wire rf_rd_en1, rf_rd_en2;
wire [4:0] rf_rd_index1, rf_rd_index2;
wire rf_rd_data1, rf_rd_data2;
wire src1_value, src2_value;
assign rf_rd_en1 = rs1Valid;
assign rf_rd_en2 = rs2Valid;
assign rf_rd_index1 = rs1;
assign rf_rd_index2 = rs2;
assign [31:0] src1_value = {31{rf_rd_data1}};
assign [31:0] src2_value = {31{rf_rd_data2}};
/* Maybe write logic ?
assign rf_wr_en = 1'b0;
assign rf_wr_index = 5'b0;
assign rf_wr_data = 32'b0;
Disabled */
// ALU FOR ADD, ADDI
wire [31:0] alu_result = 32'b0;
wire [31:0] alu_op2 = isADDI ? Iimm : src2_value;
assign alu_result = (isADDI || isADD) ? (src1_value + alu_op2) : 32'b0;
//ALU Register file connect
/*
assign rf_wr_data = alu_result;
assign rf_wr_en = rdValid && (isADD || isADDI);
assign rf_wr_index = rd;
*/
//x0 support adding
assign rf_wr_data = rf_wr_en ? alu_result : 32'b0;
assign rf_wr_en = rdValid && (isADD || isADDI) && (rd != 5'b0);
assign rf_wr_index = rd;
//Branch
if(isBType) begin
wire taken_br = (isBEQ ? src1_value == src2_value : 1'b0) ||
(isBNE ? src1_value != src2_value : 1'b0) ||
(isBLT ? ((src1_value < src2_value) ^ (src1_value[31] != src2_value[31])) : 1'b0) ||
(isBGE ? ((src1_value >= src2_value) ^ (src1_value[31] != src2_value)) : 1'b0) ||
(isBLTU ? src1_value < src2_value : 1'b0) ||
(isBGEU ? src1_value >= src2_value : 1'b0);
wire [31:0] br_tgt_pc = next_pc + Bimm;
end
endmodule