-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Misaligned pointer update. #812
Changes from 1 commit
1b0bdad
1902f4a
5b62839
5dfd05b
0f5c6a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,7 +60,7 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
output logic [31:0] instr_addr_o, | ||
output privlvl_t instr_priv_lvl_o, | ||
output logic instr_is_clic_ptr_o, // True CLIC pointer after taking a CLIC SHV interrupt | ||
output logic instr_is_mret_ptr_o, // CLIC pointer due to restarting pionter fetch during mret | ||
output logic instr_is_mret_ptr_o, // CLIC pointer due to restarting pointer fetch during mret | ||
output logic instr_is_tbljmp_ptr_o, | ||
output logic [ALBUF_CNT_WIDTH-1:0] outstnd_cnt_q_o | ||
); | ||
|
@@ -97,9 +97,10 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
// Store number of responses to flush when get get a branch | ||
logic [1:0] n_flush_n, n_flush_q, n_flush_branch; | ||
|
||
// Error propagation signals for bus and mpu | ||
// Error propagation signals for bus, mpu and alignment checker (pointers) | ||
logic bus_err_unaligned, bus_err; | ||
mpu_status_e mpu_status_unaligned, mpu_status; | ||
align_status_e align_status_unaligned, align_status; | ||
|
||
// resp_valid gated while flushing | ||
logic resp_valid_gated; | ||
|
@@ -163,9 +164,11 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
|
||
// Aligned instructions will either be fully in index 0 or incoming data | ||
// This also applies for the bus_error and mpu_status | ||
assign instr = (valid_q[rptr]) ? resp_q[rptr].bus_resp.rdata : resp_i.bus_resp.rdata; | ||
assign bus_err = (valid_q[rptr]) ? resp_q[rptr].bus_resp.err : resp_i.bus_resp.err; | ||
assign mpu_status = (valid_q[rptr]) ? resp_q[rptr].mpu_status : resp_i.mpu_status; | ||
assign instr = (valid_q[rptr]) ? resp_q[rptr].bus_resp.rdata : resp_i.bus_resp.rdata; | ||
assign bus_err = (valid_q[rptr]) ? resp_q[rptr].bus_resp.err : resp_i.bus_resp.err; | ||
assign mpu_status = (valid_q[rptr]) ? resp_q[rptr].mpu_status : resp_i.mpu_status; | ||
assign align_status = (valid_q[rptr]) ? resp_q[rptr].align_status : resp_i.align_status; | ||
|
||
|
||
// Unaligned instructions will either be split across index 0 and 1, or index 0 and incoming data | ||
assign instr_unaligned = (valid_q[rptr2]) ? {resp_q[rptr2].bus_resp.rdata[15:0], instr[31:16]} : {resp_i.bus_resp.rdata[15:0], instr[31:16]}; | ||
|
@@ -182,9 +185,10 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
assign aligned_is_compressed = instr[1:0] != 2'b11; | ||
|
||
|
||
// Set mpu_status and bus error for unaligned instructions | ||
// Set mpu_status, align_status and bus error for unaligned instructions | ||
always_comb begin | ||
mpu_status_unaligned = MPU_OK; | ||
align_status_unaligned = ALIGN_OK; | ||
bus_err_unaligned = 1'b0; | ||
// There is valid data in q1 (valid q0 is implied) | ||
if(valid_q[rptr2]) begin | ||
|
@@ -195,12 +199,18 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
mpu_status_unaligned = MPU_RE_FAULT; | ||
end | ||
|
||
if((resp_q[rptr2].align_status != MPU_OK) || (resp_q[rptr].align_status != MPU_OK)) begin | ||
align_status_unaligned = ALIGN_RE_ERR; | ||
end | ||
|
||
// Bus error from either entry | ||
bus_err_unaligned = (resp_q[rptr2].bus_resp.err || resp_q[rptr].bus_resp.err); | ||
end else begin | ||
// Compressed, use only mpu_status from q0 | ||
mpu_status_unaligned = resp_q[rptr].mpu_status; | ||
|
||
align_status_unaligned = resp_q[rptr].align_status; | ||
|
||
// bus error from q0 | ||
bus_err_unaligned = resp_q[rptr].bus_resp.err; | ||
end | ||
|
@@ -214,19 +224,24 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
mpu_status_unaligned = MPU_RE_FAULT; | ||
end | ||
|
||
if((resp_q[rptr].align_status != MPU_OK) || (resp_i.align_status != MPU_OK)) begin | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MPU_OK -> ALIGN_OK |
||
align_status_unaligned = ALIGN_RE_ERR; | ||
end | ||
|
||
// Bus error from q0 and resp_i | ||
bus_err_unaligned = (resp_q[rptr].bus_resp.err || resp_i.bus_resp.err); | ||
end else begin | ||
// There is unaligned data in q0 and it is compressed | ||
mpu_status_unaligned = resp_q[rptr].mpu_status; | ||
|
||
align_status_unaligned = resp_q[rptr].align_status; | ||
// Bus error from q0 | ||
bus_err_unaligned = resp_q[rptr].bus_resp.err; | ||
end | ||
end else begin | ||
// There is no data in the buffer, use input | ||
mpu_status_unaligned = resp_i.mpu_status; | ||
bus_err_unaligned = resp_i.bus_resp.err; | ||
mpu_status_unaligned = resp_i.mpu_status; | ||
bus_err_unaligned = resp_i.bus_resp.err; | ||
align_status_unaligned = resp_i.align_status; | ||
end | ||
end | ||
end | ||
|
@@ -238,6 +253,7 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
instr_instr_o.bus_resp.rdata = instr; | ||
instr_instr_o.bus_resp.err = bus_err; | ||
instr_instr_o.mpu_status = mpu_status; | ||
instr_instr_o.align_status = align_status; | ||
instr_valid_o = 1'b0; | ||
|
||
// Invalidate output if we get killed | ||
|
@@ -248,14 +264,15 @@ module cv32e40x_alignment_buffer import cv32e40x_pkg::*; | |
instr_instr_o.bus_resp.rdata = instr_unaligned; | ||
instr_instr_o.bus_resp.err = bus_err_unaligned; | ||
instr_instr_o.mpu_status = mpu_status_unaligned; | ||
instr_instr_o.align_status = align_status_unaligned; | ||
// No instruction valid | ||
if (!valid) begin | ||
instr_valid_o = 1'b0; | ||
// Unaligned instruction is compressed, we only need 16 upper bits from index 0 | ||
end else if (unaligned_is_compressed) begin | ||
instr_valid_o = valid; | ||
end else begin | ||
// Unaligned is not compressed, we need data form either index 0 and 1, or 0 and input | ||
// Unaligned is not compressed, we need data from either index 0 and 1, or 0 and input | ||
instr_valid_o = valid_unaligned_uncompressed; | ||
end | ||
end else begin | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. align_status should be checked wherever mpu_status is checked. Seems to be missing on line 1028: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MPU_OK -> ALIGN_OK