diff --git a/id_stage.sv b/id_stage.sv index b16d5dce..808d1050 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -275,6 +275,8 @@ module riscv_id_stage logic [31:0] hwloop_end; logic [31:0] hwloop_cnt, hwloop_cnt_int; + logic hwloop_valid; + // CSR control logic csr_access; logic [1:0] csr_op; @@ -790,7 +792,7 @@ module riscv_id_stage .hwlp_regid_i ( hwloop_regid ), // from controller - .valid_i ( instr_valid_i & is_hwlp_i ), + .valid_i ( hwloop_valid ), // to hwloop controller .hwlp_start_addr_o ( hwlp_start_o ), @@ -801,6 +803,8 @@ module riscv_id_stage .hwlp_dec_cnt_i ( hwlp_dec_cnt_i ) ); + assign hwloop_valid = instr_valid_i & clear_instr_valid_o & is_hwlp_i; + ///////////////////////////////////////////////////////////////////////////////// // ___ ____ _______ __ ____ ___ ____ _____ _ ___ _ _ _____ // @@ -949,6 +953,6 @@ module riscv_id_stage // the instruction delivered to the ID stage should always be valid assert property ( - @(posedge clk) (instr_valid_i & (~illegal_c_insn_i)) |-> (!$isunknown(instr_rdata_i)) ); + @(posedge clk) (instr_valid_i & (~illegal_c_insn_i)) |-> (!$isunknown(instr_rdata_i)) ) else $display("Instruction is valid, but has at least one X"); endmodule diff --git a/load_store_unit.sv b/load_store_unit.sv index 24129ba0..ac7254ba 100644 --- a/load_store_unit.sv +++ b/load_store_unit.sv @@ -484,4 +484,7 @@ module riscv_load_store_unit // assert that errors are only sent at the same time as grant assert property ( @(posedge clk) (data_err_i) |-> (data_gnt_i) ); + // assert that the address does not contain X when request is sent + assert property ( @(posedge clk) (data_req_o) |-> (!$isunknown(data_addr_o)) ); + endmodule diff --git a/prefetch_L0_buffer.sv b/prefetch_L0_buffer.sv index 2e9502c9..a72beb3b 100644 --- a/prefetch_L0_buffer.sv +++ b/prefetch_L0_buffer.sv @@ -142,17 +142,12 @@ module riscv_prefetch_L0_buffer begin rdata_unaligned[31:16] = 'x; - if (valid_L0) begin - case(addr_o[3:2]) - 2'b00: begin rdata_unaligned[31:16] = rdata_L0[1][15:0]; end - 2'b01: begin rdata_unaligned[31:16] = rdata_L0[2][15:0]; end - 2'b10: begin rdata_unaligned[31:16] = rdata_L0[3][15:0]; end - // this state is only interesting if we have already done a prefetch - 2'b11: begin - rdata_unaligned[31:16] = rdata_L0[0][15:0]; - end - endcase // addr_o - end + case(addr_o[3:2]) + 2'b00: begin rdata_unaligned[31:16] = rdata_L0[1][15:0]; end + 2'b01: begin rdata_unaligned[31:16] = rdata_L0[2][15:0]; end + 2'b10: begin rdata_unaligned[31:16] = rdata_L0[3][15:0]; end + 2'b11: begin rdata_unaligned[31:16] = rdata_L0[0][15:0]; end + endcase // addr_o end @@ -176,7 +171,7 @@ module riscv_prefetch_L0_buffer addr_int = addr_o; // advance address when pipeline is unstalled - if (ready_i & (~hwloop_i)) begin + if (ready_i) begin if (addr_o[1]) begin // unaligned case @@ -233,24 +228,29 @@ module riscv_prefetch_L0_buffer valid = 1'b1; if (ready_i) begin - if (next_valid) begin - if (fetch_gnt) begin - save_rdata_last = 1'b1; - NS = VALID_GRANTED; - end else - NS = VALID; - end else if (next_is_crossword) begin - if (fetch_gnt) begin - save_rdata_last = 1'b1; - NS = NOT_VALID_CROSS_GRANTED; - end else begin - NS = NOT_VALID_CROSS; - end + if (hwloop_i) begin + addr_n = addr_o; // keep the old address for now + NS = HWLP_WAIT_GNT; end else begin - if (fetch_gnt) - NS = NOT_VALID_GRANTED; - else - NS = NOT_VALID; + if (next_valid) begin + if (fetch_gnt) begin + save_rdata_last = 1'b1; + NS = VALID_GRANTED; + end else + NS = VALID; + end else if (next_is_crossword) begin + if (fetch_gnt) begin + save_rdata_last = 1'b1; + NS = NOT_VALID_CROSS_GRANTED; + end else begin + NS = NOT_VALID_CROSS; + end + end else begin + if (fetch_gnt) + NS = NOT_VALID_GRANTED; + else + NS = NOT_VALID; + end end end else begin if (fetch_valid) begin @@ -453,9 +453,10 @@ module riscv_prefetch_L0_buffer is_hwlp_n = 1'b1; addr_n = hwloop_target_i; NS = BRANCHED; - end - else + end else begin + addr_n = addr_o; // keep the old address for now NS = HWLP_WAIT_GNT; + end end else begin if (fetch_gnt) begin save_rdata_hwlp = 1'b1; @@ -516,6 +517,12 @@ module riscv_prefetch_L0_buffer assert property ( @(posedge clk) (ready_i) |-> (valid_o) ) else $warning("IF Stage is ready without prefetcher having valid data"); + // never is_crossword while also next_is_crossword + assert property ( + @(posedge clk) (next_is_crossword) |-> (~is_crossword) ) else $warning("Cannot have two crossword accesses back-to-back"); + assert property ( + @(posedge clk) (is_crossword) |-> (~next_is_crossword) ) else $warning("Cannot have two crossword accesses back-to-back"); + endmodule // prefetch_L0_buffer