FINAL FINAL
This commit is contained in:
@@ -120,7 +120,9 @@ module RISCCore (
|
|||||||
wire isJALR = (opcode == 7'b1100111) && (funct3 == 3'b000);
|
wire isJALR = (opcode == 7'b1100111) && (funct3 == 3'b000);
|
||||||
|
|
||||||
//Mem address calculation
|
//Mem address calculation
|
||||||
wire [31:0] mem_addr = (is_mem_op) ? alu_result : 32'b0;
|
/*wire [31:0] mem_addr = (is_mem_op) ? alu_result : 32'b0;
|
||||||
|
Using direct */
|
||||||
|
wire [31:0] mem_addr = rs1_val + (isSType ? Simm : Iimm);
|
||||||
|
|
||||||
//Mem address logic
|
//Mem address logic
|
||||||
//For simplicity we only implement all loads as word loads (lw)
|
//For simplicity we only implement all loads as word loads (lw)
|
||||||
@@ -153,40 +155,52 @@ module RISCCore (
|
|||||||
end
|
end
|
||||||
|
|
||||||
//Store operations
|
//Store operations
|
||||||
always @(*) begin
|
always @(posedge clk) begin
|
||||||
if (!rst && is_store && (word_addr < 32) && (mem_addr[1:0] == 2'b00)) begin
|
if (!rst && is_store && (word_addr < 32) && (mem_addr[1:0] == 2'b00)) begin
|
||||||
|
|
||||||
case (funct3)
|
case (funct3)
|
||||||
3'b000: begin //SB: store byte 0
|
3'b000: dmem[word_addr] <= {dmem[word_addr][31:8], rs2_val[7:0]}; // SB
|
||||||
dmem[word_addr][7:0] = rs2_val[7:0];
|
3'b001: dmem[word_addr] <= {dmem[word_addr][31:16], rs2_val[15:0]}; // SH
|
||||||
end
|
3'b010: dmem[word_addr] <= rs2_val; // SW
|
||||||
3'b001: begin //SH: store halfword
|
|
||||||
dmem[word_addr][15:0] = rs2_val[15:0];
|
|
||||||
end
|
|
||||||
3'b010: begin //SW: store word
|
|
||||||
dmem[word_addr] = rs2_val;
|
|
||||||
end
|
|
||||||
endcase
|
endcase
|
||||||
|
// The $display can be simplified now as well
|
||||||
$display("MEM Write: word_addr=%h, data=%h", word_addr, rs2_val);
|
$display("MEM Write: word_addr=%h, data=%h", word_addr, rs2_val);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
// ALU operations
|
// ALU operations
|
||||||
|
|
||||||
//sltu and slt
|
//sltu and slt
|
||||||
wire [31:0] sltu_rslt = {31'b0, (rs1_val < rs2_val)};
|
// For signed operations, cast the inputs to 'signed'.
|
||||||
wire [31:0] signed_slt = (rs1_val[31] && !rs2_val[31]) ? 1'b1 :
|
// Verilog will then use 2's complement arithmetic automatically.
|
||||||
(!rs1_val[31] && rs2_val[31]) ? 1'b0 :
|
wire signed [31:0] signed_rs1_val = rs1_val;
|
||||||
(rs1_val < rs2_val);
|
wire signed [31:0] signed_Iimm = Iimm;
|
||||||
wire [31:0] slt_rslt = {31'b0, signed_slt};
|
|
||||||
wire [31:0] slti_rslt = ((rs1_val[31] == Iimm[31]) ? sltu_rslt : {31'b0, rs1_val[31]});
|
|
||||||
|
|
||||||
wire [63:0] SErs1_val = {{32{rs1_val[31]}}, (rs1_val < rs2_val)};
|
// SLTU: Set if Less Than (Unsigned)
|
||||||
|
// Compares rs1_val and rs2_val as unsigned integers.
|
||||||
|
wire [31:0] sltu_rslt = (rs1_val < rs2_val) ? 32'd1 : 32'd0;
|
||||||
|
|
||||||
wire [63:0] sra_rslt = {SErs1_val >> rs2_val[4:0]};
|
// SLT: Set if Less Than (Signed)
|
||||||
wire [63:0] srai_rslt = {SErs1_val >> Iimm[4:0]};
|
// Compares rs1_val and rs2_val as signed integers.
|
||||||
wire [31:0] sltiu_rslt = {31'b0, (rs1_val < Iimm)};
|
wire [31:0] slt_rslt = (signed_rs1_val < $signed(rs2_val)) ? 32'd1 : 32'd0;
|
||||||
|
|
||||||
wire [31:0] alu_result = (is_mem_op) ? (rs1_val + Iimm) : // Mem address computation
|
// SLTIU: Set if Less Than Immediate (Unsigned)
|
||||||
(isADDI) ? (rs1_val + Iimm) :
|
// Compares rs1_val (unsigned) with the sign-extended immediate (unsigned).
|
||||||
|
wire [31:0] sltiu_rslt = (rs1_val < Iimm) ? 32'd1 : 32'd0;
|
||||||
|
|
||||||
|
// SLTI: Set if Less Than Immediate (Signed)
|
||||||
|
// Compares rs1_val and the immediate as signed integers.
|
||||||
|
wire [31:0] slti_rslt = (signed_rs1_val < signed_Iimm) ? 32'd1 : 32'd0;
|
||||||
|
|
||||||
|
// SRA: Shift Right Arithmetic
|
||||||
|
// Shifts signed_rs1_val right by the amount in rs2_val[4:0].
|
||||||
|
// The '>>>' operator performs an arithmetic shift, preserving the sign bit.
|
||||||
|
wire [31:0] sra_rslt = signed_rs1_val >>> rs2_val[4:0];
|
||||||
|
|
||||||
|
// SRAI: Shift Right Arithmetic Immediate
|
||||||
|
// Shifts signed_rs1_val right by the immediate amount in Iimm[4:0].
|
||||||
|
wire [31:0] srai_rslt = signed_rs1_val >>> Iimm[4:0];
|
||||||
|
|
||||||
|
wire [31:0] alu_result = (isADDI) ? (rs1_val + Iimm) :
|
||||||
(isADD) ? (rs1_val + rs2_val) :
|
(isADD) ? (rs1_val + rs2_val) :
|
||||||
(isSLT) ? slt_rslt :
|
(isSLT) ? slt_rslt :
|
||||||
(isSLTU) ? sltu_rslt :
|
(isSLTU) ? sltu_rslt :
|
||||||
@@ -203,11 +217,11 @@ end
|
|||||||
(isSLL) ? (rs1_val << rs2_val[4:0]) :
|
(isSLL) ? (rs1_val << rs2_val[4:0]) :
|
||||||
(isSRL) ? (rs1_val >> rs2_val[4:0]) :
|
(isSRL) ? (rs1_val >> rs2_val[4:0]) :
|
||||||
(isSLTIU) ? (sltiu_rslt) :
|
(isSLTIU) ? (sltiu_rslt) :
|
||||||
(isLUI) ? ({Iimm[31:12], 12'b0}) :
|
(isLUI) ? Uimm :
|
||||||
(isAUIPC) ? (pc + Iimm) :
|
(isAUIPC) ? (pc + Uimm) :
|
||||||
(isJAL || isJALR) ? (pc + 32'd4) :
|
(isJAL || isJALR) ? (pc + 32'd4) :
|
||||||
(isSRA) ? (sra_rslt[31:0]) :
|
(isSRA) ? sra_rslt :
|
||||||
(isSRAI) ? (srai_rslt[31:0]) :
|
(isSRAI) ? srai_rslt :
|
||||||
32'b0;
|
32'b0;
|
||||||
|
|
||||||
|
|
||||||
@@ -226,10 +240,11 @@ end
|
|||||||
// Next PC calculation - FIXED: using wire for continuous assignment
|
// Next PC calculation - FIXED: using wire for continuous assignment
|
||||||
wire [31:0] branch_target = pc + Bimm;
|
wire [31:0] branch_target = pc + Bimm;
|
||||||
wire [31:0] next_pc_base = pc + 32'h4;
|
wire [31:0] next_pc_base = pc + 32'h4;
|
||||||
wire [31:0] jalr_tgt_pc = rs1_val + Iimm;
|
wire [31:0] jalr_tgt_pc = (rs1_val + Iimm) & 32'hFFFFFFFE;
|
||||||
|
wire [31:0] jal_target = pc + Jimm;
|
||||||
|
|
||||||
assign next_pc = branch_taken ? branch_target :
|
assign next_pc = branch_taken ? branch_target :
|
||||||
isJAL ? branch_target :
|
isJAL ? jal_target :
|
||||||
isJALR ? jalr_tgt_pc :
|
isJALR ? jalr_tgt_pc :
|
||||||
next_pc_base;
|
next_pc_base;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user