fix issue of jumping to address 0
This commit is contained in:
119
hdl/core.v
119
hdl/core.v
@ -2,16 +2,30 @@ module core(
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
// Memory - instruction
|
||||
output reg [31:0] mem_inst_addr,
|
||||
input [31:0] mem_inst_data,
|
||||
|
||||
// output reg [31:0] mem_data_addr,
|
||||
// // Memory - data
|
||||
output reg [31:0] mem_data_addr,
|
||||
input [31:0] mem_data_rdata,
|
||||
output reg [31:0] mem_data_wdata,
|
||||
output reg [(32/8)-1:0] mem_data_wmask,
|
||||
output reg mem_data_we,
|
||||
|
||||
// output reg [31:0] mem_data_waddr,
|
||||
// output reg [31:0] mem_data_wdata,
|
||||
// input [31:0] mem_data_rdata,
|
||||
// output reg mem_data_en,
|
||||
// output reg mem_data_we,
|
||||
// input mem_data_valid,
|
||||
// input mem_data_done
|
||||
// output reg [3:0] mem_data_wmask,
|
||||
// output reg mem_data_wvalid,
|
||||
// input wire mem_data_wready,
|
||||
|
||||
// output reg [31:0] mem_data_raddr,
|
||||
// output reg mem_data_raddr_valid,
|
||||
// input wire mem_data_raddr_ready,
|
||||
|
||||
// input wire [31:0] mem_data_rdata,
|
||||
// input wire mem_data_rdata_valid,
|
||||
// output reg mem_data_rdata_ready,
|
||||
|
||||
|
||||
// // instruction memory
|
||||
@ -78,21 +92,26 @@ initial begin : init_regfile
|
||||
end
|
||||
|
||||
// Registers
|
||||
reg [31:0] r_if_pc = 0, r_id_pc, r_ex_pc, r_mem_pc, r_wb_pc;
|
||||
reg [31:0] r_id_inst, r_ex_inst, r_mem_inst, r_wb_inst;
|
||||
reg [4:0] r_ex_rd, r_mem_rd, r_wb_rd;
|
||||
reg [3:0] r_ex_aluop;
|
||||
reg [31:0] r_ex_s1, r_ex_s2, r_mem_s1, r_mem_s2;
|
||||
reg [31:0] r_mem_alu_out, r_wb_alu_out;
|
||||
reg r_mem_alu_zero;
|
||||
reg r_ex_jump;
|
||||
reg r_ex_store, r_mem_store;
|
||||
reg r_ex_load, r_mem_load;
|
||||
reg [31:0] r_mem_wdata, r_wb_wdata;
|
||||
reg r_id_valid=0, r_ex_valid=0, r_mem_valid=0, r_wb_valid=0;
|
||||
reg r_ex_branch_pol;
|
||||
reg r_ex_branch, r_mem_branch, r_wb_branch;
|
||||
reg [31:0] r_ex_immed_btype;
|
||||
reg [31:0] r_if_pc = 0, r_id_pc, r_ex_pc, r_mem_pc, r_wb_pc;
|
||||
reg [31:0] r_id_inst, r_ex_inst, r_mem_inst, r_wb_inst;
|
||||
reg r_id_valid=0, r_ex_valid=0, r_mem_valid=0, r_wb_valid=0;
|
||||
reg [4:0] r_ex_rs1, r_mem_rs1, r_wb_rs1;
|
||||
reg [4:0] r_ex_rs2, r_mem_rs2, r_wb_rs2;
|
||||
reg [4:0] r_ex_rd, r_mem_rd, r_wb_rd;
|
||||
reg [3:0] r_ex_aluop;
|
||||
reg [31:0] r_ex_s1, r_mem_s1;
|
||||
reg [31:0] r_ex_s2, r_mem_s2;
|
||||
reg [31:0] r_mem_alu_out, r_wb_alu_out;
|
||||
reg r_mem_alu_zero;
|
||||
reg r_ex_jump, r_mem_jump, r_wb_jump;
|
||||
reg r_ex_store, r_mem_store;
|
||||
reg r_ex_load, r_mem_load, r_wb_load;
|
||||
reg [31:0] r_mem_wdata, r_wb_wdata;
|
||||
reg r_ex_branch_pol;
|
||||
reg r_ex_branch, r_mem_branch, r_wb_branch;
|
||||
reg [31:0] r_ex_immed_btype;
|
||||
reg [31:0] r_mem_ra, r_wb_ra;
|
||||
reg [31:0] r_wb_load_data;
|
||||
|
||||
// IF
|
||||
reg s_if_stall = 0;
|
||||
@ -240,9 +259,12 @@ always @(*) begin
|
||||
// OP_LOAD: begin
|
||||
|
||||
// end
|
||||
// OP_STORE: begin
|
||||
|
||||
// end
|
||||
OP_STORE: begin
|
||||
s_id_store = 1;
|
||||
s_id_s1 = regfile[s_id_rs1];
|
||||
s_id_s2 = s_id_immed_stype;
|
||||
// TODO: finish parsing (byte vs word. For now always assume word)
|
||||
end
|
||||
OP_IMM: begin
|
||||
s_id_s1 = regfile[s_id_rs1];
|
||||
s_id_s2 = s_id_immed_itype;
|
||||
@ -309,9 +331,9 @@ reg s_ex_stall = 0;
|
||||
reg [31:0] s_ex_data1, s_ex_data2;
|
||||
reg [31:0] s_ex_alu_out;
|
||||
reg s_ex_alu_zero;
|
||||
reg [31:0] s_ex_wdata;
|
||||
reg s_ex_take_branch;
|
||||
reg [31:0] s_ex_branch_addr;
|
||||
reg [31:0] s_ex_ra;
|
||||
|
||||
always @(*) begin
|
||||
s_ex_stall = s_mem_stall;
|
||||
@ -358,11 +380,10 @@ always @(*) begin
|
||||
s_ex_alu_zero = (s_ex_alu_out == 0);
|
||||
|
||||
s_ex_take_branch = r_ex_valid && (r_ex_jump || (r_ex_branch && (s_ex_alu_zero ^ r_ex_branch_pol)));
|
||||
s_ex_ra = r_ex_pc + 4;
|
||||
if (r_ex_jump) begin
|
||||
s_ex_wdata = r_ex_pc + 4;
|
||||
s_ex_branch_addr = s_ex_alu_out;
|
||||
end else begin
|
||||
s_ex_wdata = s_ex_alu_out;
|
||||
s_ex_branch_addr = r_ex_pc + r_ex_immed_btype;
|
||||
end
|
||||
end
|
||||
@ -370,24 +391,17 @@ end
|
||||
// MEM
|
||||
reg s_mem_stall = 0;
|
||||
reg s_mem_bp;
|
||||
reg [31:0] s_mem_load_data;
|
||||
|
||||
always @(*) begin
|
||||
s_mem_stall = 0; // TODO: add stall logic when actually reading/writing
|
||||
s_mem_bp = 0;
|
||||
|
||||
// if (r_mem_store) begin
|
||||
// mem_data_en = 1;
|
||||
// mem_data_we = 1;
|
||||
// s_mem_bp = !mem_data_done;
|
||||
// end else if (r_mem_load) begin
|
||||
// mem_data_en = 1;
|
||||
// mem_data_we = 0;
|
||||
// s_mem_bp = !mem_data_valid;
|
||||
// end else begin
|
||||
// mem_data_en = 0;
|
||||
// mem_data_we = 0;
|
||||
// s_mem_bp = 0;
|
||||
// end
|
||||
mem_data_addr = r_mem_alu_out;
|
||||
mem_data_wdata = regfile[r_mem_rs2];
|
||||
mem_data_wmask = 4'b1111; // TODO: implement smaller writes
|
||||
mem_data_we = r_mem_store && r_mem_valid;
|
||||
s_mem_load_data = mem_data_rdata; // TODO: implement smaller reads
|
||||
end
|
||||
|
||||
// WB
|
||||
@ -397,7 +411,13 @@ reg s_wb_write;
|
||||
always @(*) begin
|
||||
|
||||
// load instructions do not use output of alu in wb
|
||||
s_wb_data = r_wb_wdata;
|
||||
if (r_wb_jump) begin
|
||||
s_wb_data = r_wb_ra;
|
||||
end else if (r_wb_load) begin
|
||||
s_wb_data = r_wb_load_data;
|
||||
end else begin
|
||||
s_wb_data = r_wb_alu_out;
|
||||
end
|
||||
|
||||
// FIXME: always writes!!!
|
||||
s_wb_write = (r_wb_branch == 0);
|
||||
@ -433,13 +453,10 @@ always @(posedge clk) begin: pipeline_update
|
||||
r_mem_alu_zero <= 0;
|
||||
r_mem_store <= 0;
|
||||
r_mem_load <= 0;
|
||||
r_mem_wdata <= 0;
|
||||
|
||||
r_wb_pc <= 0;
|
||||
r_wb_inst <= INST_NOP;
|
||||
r_wb_rd <= 0;
|
||||
r_wb_alu_out <= 0;
|
||||
r_wb_wdata <= 0;
|
||||
|
||||
for (i=1; i<32; i=i+1) begin
|
||||
regfile[i] <= 0;
|
||||
@ -462,6 +479,8 @@ always @(posedge clk) begin: pipeline_update
|
||||
if (!s_ex_stall) begin
|
||||
r_ex_pc <= r_id_pc;
|
||||
r_ex_inst <= r_id_inst;
|
||||
r_ex_rs1 <= s_id_rs1;
|
||||
r_ex_rs2 <= s_id_rs2;
|
||||
r_ex_rd <= s_id_rd;
|
||||
r_ex_s1 <= s_id_s1;
|
||||
r_ex_s2 <= s_id_s2;
|
||||
@ -480,6 +499,8 @@ always @(posedge clk) begin: pipeline_update
|
||||
if (!s_mem_stall) begin
|
||||
r_mem_pc <= r_ex_pc;
|
||||
r_mem_inst <= r_ex_inst;
|
||||
r_mem_rs1 <= r_ex_rs1;
|
||||
r_mem_rs2 <= r_ex_rs2;
|
||||
r_mem_rd <= r_ex_rd;
|
||||
r_mem_s1 <= r_ex_s1;
|
||||
r_mem_s2 <= r_ex_s2;
|
||||
@ -487,20 +508,26 @@ always @(posedge clk) begin: pipeline_update
|
||||
r_mem_alu_zero <= s_ex_alu_zero;
|
||||
r_mem_store <= r_ex_store;
|
||||
r_mem_load <= r_ex_load;
|
||||
r_mem_wdata <= s_ex_wdata;
|
||||
r_mem_valid <= r_ex_valid;
|
||||
r_mem_branch <= r_ex_branch;
|
||||
r_mem_ra <= s_ex_ra;
|
||||
r_mem_jump <= r_ex_jump;
|
||||
end
|
||||
|
||||
// WB
|
||||
if (1) begin
|
||||
r_wb_pc <= r_mem_pc;
|
||||
r_wb_inst <= r_mem_inst;
|
||||
r_wb_rs1 <= r_mem_rs1;
|
||||
r_wb_rs2 <= r_mem_rs2;
|
||||
r_wb_rd <= r_mem_rd;
|
||||
r_wb_alu_out <= r_mem_alu_out;
|
||||
r_wb_wdata <= r_mem_wdata;
|
||||
r_wb_valid <= r_mem_valid;
|
||||
r_wb_branch <= r_mem_branch;
|
||||
r_wb_ra <= r_mem_ra;
|
||||
r_wb_jump <= r_mem_jump;
|
||||
r_wb_load <= r_mem_load;
|
||||
r_wb_load_data <= s_mem_load_data;
|
||||
end
|
||||
|
||||
// Register File
|
||||
|
Reference in New Issue
Block a user