mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 13:47:13 -04:00
🐛 Fix bug in misaligned ld/st exception
This commit is contained in:
parent
121852957b
commit
0abbabad86
5 changed files with 25 additions and 23 deletions
2
Makefile
2
Makefile
|
@ -40,7 +40,7 @@ riscv-tests = rv64ui-p-add rv64ui-p-addi rv64ui-p-slli rv64ui-p-addiw rv64ui-p-a
|
|||
rv64ui-p-sraiw rv64ui-p-sraw rv64ui-p-srl rv64ui-p-srli rv64ui-p-srliw rv64ui-p-srlw \
|
||||
rv64ui-p-lb rv64ui-p-lbu rv64ui-p-ld rv64ui-p-lh rv64ui-p-lhu rv64ui-p-lui \
|
||||
rv64ui-p-lw rv64ui-p-lwu \
|
||||
rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal
|
||||
rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal rv64mi-p-ma_addr
|
||||
|
||||
riscv-test = rv64ui-p-add
|
||||
# Search here for include files (e.g.: non-standalone components)
|
||||
|
|
|
@ -69,5 +69,5 @@ Check out the [contribution guide](CONTRIBUTING.md)
|
|||
| **Test Name** | **P/F/U** | **Test Name** | **P/F/U** | **Test Name** | **P/F/U** |
|
||||
|---------------|----------------------|---------------|----------------------|---------------|----------------------|
|
||||
| csr | :white_check_mark: | illegal | :white_check_mark: | mcsr | :white_check_mark: |
|
||||
| breakpoint | :white_large_square: | ma_addr | :white_large_square: | ma_fetch | :white_large_square: |
|
||||
| breakpoint | :white_large_square: | ma_addr | :white_check_mark: | ma_fetch | :white_large_square: |
|
||||
| sbreak | :white_large_square: | scall | :white_large_square: | | |
|
||||
|
|
|
@ -296,6 +296,8 @@ module load_unit (
|
|||
ready_o = 1'b1;
|
||||
// do not push this request
|
||||
push = 1'b0;
|
||||
// reset state machine
|
||||
NS = IDLE;
|
||||
end
|
||||
// if we just flushed and the queue is not empty or we are getting an rvalid this cycle wait in a extra stage
|
||||
if (flush_i && (!empty || data_rvalid_i)) begin
|
||||
|
@ -309,6 +311,9 @@ module load_unit (
|
|||
always_comb begin : rvalid_output
|
||||
pop = 1'b0;
|
||||
valid_o = 1'b0;
|
||||
// output the queue data directly, the valid signal is set corresponding to the process above
|
||||
trans_id_o = out_data.trans_id;
|
||||
|
||||
// we got an rvalid and are currently not flushing
|
||||
if (data_rvalid_i && CS != WAIT_FLUSH) begin
|
||||
pop = 1'b1;
|
||||
|
@ -316,12 +321,13 @@ module load_unit (
|
|||
end
|
||||
// pass through an exception
|
||||
if (valid_i && ex_i.valid) begin
|
||||
valid_o = 1'b1;
|
||||
valid_o = 1'b1;
|
||||
// in case of an exception we can use the current trans_id since we either stalled
|
||||
// or we are taking the exception in the first cycle
|
||||
trans_id_o = trans_id_i;
|
||||
end
|
||||
end
|
||||
|
||||
// output the queue data directly, the valid signal is set corresponding to the process above
|
||||
assign trans_id_o = out_data.trans_id;
|
||||
|
||||
// latch physical address
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
|
|
30
src/lsu.sv
30
src/lsu.sv
|
@ -335,19 +335,15 @@ module lsu #(
|
|||
ld_valid_i = 1'b0;
|
||||
st_valid_i = 1'b0;
|
||||
|
||||
// only activate one of the units if we didn't got an misaligned exception
|
||||
// we can directly output a misaligned exception and do not need to process it any further
|
||||
if (!data_misaligned) begin
|
||||
// check the operator to activate the right functional unit accordingly
|
||||
unique case (fu)
|
||||
// all loads go here
|
||||
LOAD: ld_valid_i = lsu_valid_i;
|
||||
// all stores go here
|
||||
STORE: st_valid_i = lsu_valid_i;
|
||||
// not relevant for the LSU
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
// check the operator to activate the right functional unit accordingly
|
||||
unique case (fu)
|
||||
// all loads go here
|
||||
LOAD: ld_valid_i = lsu_valid_i;
|
||||
// all stores go here
|
||||
STORE: st_valid_i = lsu_valid_i;
|
||||
// not relevant for the LSU
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
@ -424,13 +420,13 @@ module lsu #(
|
|||
end
|
||||
// word
|
||||
LW, LWU, SW: begin
|
||||
if (vaddr_i[2] == 1'b1 && vaddr_i[2:0] != 3'b100)
|
||||
if (vaddr_i[1:0] != 1'b00)
|
||||
data_misaligned = 1'b1;
|
||||
end
|
||||
|
||||
// half word
|
||||
LH, LHU, SH: begin
|
||||
if (vaddr_i[2:0] == 3'b111)
|
||||
if (vaddr_i[0] != 1'b0)
|
||||
data_misaligned = 1'b1;
|
||||
end
|
||||
// byte -> is always aligned
|
||||
|
@ -442,15 +438,15 @@ module lsu #(
|
|||
|
||||
if (fu == LOAD) begin
|
||||
misaligned_exception = {
|
||||
64'b0,
|
||||
LD_ADDR_MISALIGNED,
|
||||
vaddr,
|
||||
1'b1
|
||||
};
|
||||
|
||||
end else if (fu == STORE) begin
|
||||
misaligned_exception = {
|
||||
64'b0,
|
||||
ST_ADDR_MISALIGNED,
|
||||
vaddr,
|
||||
1'b1
|
||||
};
|
||||
end
|
||||
|
|
|
@ -102,7 +102,7 @@ module store_unit (
|
|||
if (ex_i.valid) begin
|
||||
// result is valid
|
||||
valid_o = 1'b1;
|
||||
// do not store this
|
||||
// do not store this
|
||||
st_valid = 1'b0;
|
||||
// we are ready if we got this exception
|
||||
ready_o = 1'b1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue