riscv single cycle
This commit is contained in:
120
chapter4/RISCcore2.v
Normal file
120
chapter4/RISCcore2.v
Normal file
@@ -0,0 +1,120 @@
|
||||
module RISCcore2 (
|
||||
input rst,
|
||||
input clk,
|
||||
output reg [31:0] pc,
|
||||
output reg [31:0] next_pc,
|
||||
output wire [31:0] instr
|
||||
);
|
||||
|
||||
// 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));
|
||||
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];
|
||||
|
||||
// FIXED: Removed extra spaces in immediate concatenations
|
||||
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
|
||||
wire isBEQ = (funct3 == 3'b000 && isBType);
|
||||
wire isBNE = (funct3 == 3'b001 && isBType);
|
||||
wire isBLT = (funct3 == 3'b100 && isBType);
|
||||
wire isBGE = (funct3 == 3'b101 && isBType);
|
||||
wire isBLTU = (funct3 == 3'b110 && isBType);
|
||||
wire isBGEU = (funct3 == 3'b111 && isBType);
|
||||
|
||||
wire isADDI = (funct3 == 3'b000 && isIType);
|
||||
wire isADD = (funct7[5] == 1'b0 && isRType && (funct3 == 3'b000));
|
||||
|
||||
// Register file signals
|
||||
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 [31:0] rf_rd_data1, rf_rd_data2;
|
||||
wire [31:0] src1_value, src2_value;
|
||||
|
||||
// Connect register file read ports
|
||||
assign rf_rd_en1 = rs1Valid;
|
||||
assign rf_rd_en2 = rs2Valid;
|
||||
assign rf_rd_index1 = rs1;
|
||||
assign rf_rd_index2 = rs2;
|
||||
|
||||
// Connect outputs
|
||||
assign src1_value = rf_rd_data1;
|
||||
assign src2_value = rf_rd_data2;
|
||||
|
||||
// ALU FOR ADD, ADDI
|
||||
wire [31:0] alu_result;
|
||||
wire [31:0] alu_op2 = isADDI ? Iimm : src2_value;
|
||||
assign alu_result = (isADDI || isADD) ? (src1_value + alu_op2) : 32'b0;
|
||||
|
||||
// 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 logic
|
||||
wire taken_br;
|
||||
wire [31:0] br_tgt_pc;
|
||||
|
||||
// Manual signed comparison for BLT and BGE
|
||||
wire signed_lt = (src1_value[31] && !src2_value[31]) ? 1'b1 : // src1 negative, src2 positive
|
||||
(!src1_value[31] && src2_value[31]) ? 1'b0 : // src1 positive, src2 negative
|
||||
(src1_value < src2_value); // same sign, compare normally
|
||||
|
||||
wire signed_ge = (src1_value[31] && !src2_value[31]) ? 1'b0 : // src1 negative, src2 positive
|
||||
(!src1_value[31] && src2_value[31]) ? 1'b1 : // src1 positive, src2 negative
|
||||
(src1_value >= src2_value); // same sign, compare normally
|
||||
|
||||
// Branch condition calculation
|
||||
assign taken_br =
|
||||
isBEQ ? (src1_value == src2_value) :
|
||||
isBNE ? (src1_value != src2_value) :
|
||||
isBLT ? signed_lt :
|
||||
isBGE ? signed_ge :
|
||||
isBLTU ? (src1_value < src2_value) :
|
||||
isBGEU ? (src1_value >= src2_value) :
|
||||
1'b0;
|
||||
|
||||
// Branch target calculation
|
||||
assign br_tgt_pc = pc + Bimm;
|
||||
|
||||
// PC logic
|
||||
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
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user