diff --git a/hw/rtl/VX_csr_unit.v b/hw/rtl/VX_csr_unit.v index 61755266..1689121a 100644 --- a/hw/rtl/VX_csr_unit.v +++ b/hw/rtl/VX_csr_unit.v @@ -41,7 +41,9 @@ module VX_csr_unit #( wire csr_we_s1; wire [`CSR_ADDR_BITS-1:0] csr_addr_s1; wire [31:0] csr_read_data, csr_read_data_s1; - wire [31:0] csr_updated_data_s1; + wire [31:0] csr_updated_data_s1; + + wire write_enable = csr_pipe_rsp_if.valid && csr_we_s1; VX_csr_data #( .CORE_ID(CORE_ID) @@ -54,7 +56,7 @@ module VX_csr_unit #( .read_addr (csr_pipe_req_if.csr_addr), .read_wid (csr_pipe_req_if.wid), .read_data (csr_read_data), - .write_enable (csr_we_s1), + .write_enable (write_enable), .write_addr (csr_addr_s1), .write_wid (csr_pipe_rsp_if.wid), .write_data (csr_updated_data_s1[`CSR_WIDTH-1:0]), @@ -89,21 +91,22 @@ module VX_csr_unit #( default: csr_updated_data = 32'hdeadbeef; endcase end - - wire csr_we_s0 = csr_we_s0_unqual && csr_pipe_req_if.valid; - wire stall = (~csr_pipe_rsp_if.ready && csr_pipe_rsp_if.valid) - || fpu_pending[csr_pipe_req_if.wid]; + wire stall_in = fpu_pending[csr_pipe_req_if.wid]; + + wire pipe_req_valid_qual = csr_pipe_req_if.valid && !stall_in; + + wire stall_out = ~csr_pipe_rsp_if.ready && csr_pipe_rsp_if.valid; VX_generic_register #( .N(1 + `NW_BITS + `NUM_THREADS + 32 + `NR_BITS + 1 + 1 + `CSR_ADDR_BITS + 1 + 32 + 32) ) pipe_reg ( .clk (clk), .reset (reset), - .stall (stall), + .stall (stall_out), .flush (1'b0), - .in ({csr_pipe_req_if.valid, csr_pipe_req_if.wid, csr_pipe_req_if.tmask, csr_pipe_req_if.PC, csr_pipe_req_if.rd, csr_pipe_req_if.wb, csr_we_s0, csr_pipe_req_if.csr_addr, csr_pipe_req_if.is_io, csr_read_data_qual, csr_updated_data}), - .out ({csr_pipe_rsp_if.valid, csr_pipe_rsp_if.wid, csr_pipe_rsp_if.tmask, csr_pipe_rsp_if.PC, csr_pipe_rsp_if.rd, csr_pipe_rsp_if.wb, csr_we_s1, csr_addr_s1, select_io_rsp, csr_read_data_s1, csr_updated_data_s1}) + .in ({pipe_req_valid_qual, csr_pipe_req_if.wid, csr_pipe_req_if.tmask, csr_pipe_req_if.PC, csr_pipe_req_if.rd, csr_pipe_req_if.wb, csr_we_s0_unqual, csr_pipe_req_if.csr_addr, csr_pipe_req_if.is_io, csr_read_data_qual, csr_updated_data}), + .out ({csr_pipe_rsp_if.valid, csr_pipe_rsp_if.wid, csr_pipe_rsp_if.tmask, csr_pipe_rsp_if.PC, csr_pipe_rsp_if.rd, csr_pipe_rsp_if.wb, csr_we_s1, csr_addr_s1, select_io_rsp, csr_read_data_s1, csr_updated_data_s1}) ); for (genvar i = 0; i < `NUM_THREADS; i++) begin @@ -113,7 +116,7 @@ module VX_csr_unit #( end // can accept new request? - assign csr_pipe_req_if.ready = ~stall; + assign csr_pipe_req_if.ready = ~(stall_out || stall_in); // pending request reg [`NUM_WARPS-1:0] pending_r; diff --git a/hw/rtl/VX_scoreboard.v b/hw/rtl/VX_scoreboard.v index 6fca200f..58c73b50 100644 --- a/hw/rtl/VX_scoreboard.v +++ b/hw/rtl/VX_scoreboard.v @@ -51,7 +51,9 @@ module VX_scoreboard #( inuse_registers[{ibuf_deq_if.wid, ibuf_deq_if.rd}] <= ibuf_deq_if.tmask; end if (release_reg) begin - assert(inuse_reg_mask[writeback_if.wid][writeback_if.rd] != 0); + assert(inuse_reg_mask[writeback_if.wid][writeback_if.rd] != 0) + else $error("*** %t: core%0d: invalid writeback register: wid=%0d, PC=%0h, rd=%0d", + $time, CORE_ID, writeback_if.wid, writeback_if.PC, writeback_if.rd); inuse_registers[{writeback_if.wid, writeback_if.rd}] <= inuse_registers_n; end inuse_reg_mask <= inuse_reg_mask_n; @@ -79,7 +81,7 @@ module VX_scoreboard #( stall_ctr <= 0; end else if (ibuf_deq_if.valid && ~ibuf_deq_if.ready) begin stall_ctr <= stall_ctr + 1; - assert(stall_ctr < 100000) else $error("%t: core%0d-stalled: wid=%0d, PC=%0h, rd=%0d, wb=%0d, inuse=%b%b%b%b, exe=%b, gpr=%b", + assert(stall_ctr < 100000) else $error("*** %t: core%0d-stalled: wid=%0d, PC=%0h, rd=%0d, wb=%0d, inuse=%b%b%b%b, exe=%b, gpr=%b", $time, CORE_ID, ibuf_deq_if.wid, ibuf_deq_if.PC, ibuf_deq_if.rd, ibuf_deq_if.wb, inuse_regs[ibuf_deq_if.rd], inuse_regs[ibuf_deq_if.rs1], inuse_regs[ibuf_deq_if.rs2], inuse_regs[ibuf_deq_if.rs3], exe_delay, gpr_delay); end else if (ibuf_deq_if.valid && ibuf_deq_if.ready) begin diff --git a/hw/simulate/simulator.cpp b/hw/simulate/simulator.cpp index ed22d3a3..45fc9056 100644 --- a/hw/simulate/simulator.cpp +++ b/hw/simulate/simulator.cpp @@ -61,6 +61,10 @@ void Simulator::reset() { print_bufs_.clear(); dram_rsp_vec_.clear(); + dram_rsp_active_ = false; + snp_req_active_ = false; + csr_req_active_ = false; + snp_req_size_ = 0; pending_snp_reqs_ = 0; csr_rsp_value_ = nullptr; @@ -91,6 +95,10 @@ void Simulator::step() { vortex_->clk = 0; this->eval(); + + dram_rsp_ready_ = vortex_->dram_rsp_ready; + snp_req_ready_ = vortex_->snp_req_ready; + csr_io_req_ready_ = vortex_->csr_io_req_ready; vortex_->clk = 1; this->eval(); @@ -132,7 +140,7 @@ void Simulator::eval_dram_bus() { // send DRAM response if (dram_rsp_active_ - && vortex_->dram_rsp_valid && vortex_->dram_rsp_ready) { + && vortex_->dram_rsp_valid && dram_rsp_ready_) { dram_rsp_active_ = false; } if (!dram_rsp_active_) { @@ -205,7 +213,7 @@ void Simulator::eval_io_bus() { void Simulator::eval_snp_bus() { if (snp_req_active_) { - if (vortex_->snp_req_valid && vortex_->snp_req_ready) { + if (vortex_->snp_req_valid && snp_req_ready_) { assert(snp_req_size_); #ifdef DBG_PRINT_CACHE_SNP std::cout << std::dec << timestamp << ": [sim] SNP Req: addr=" << std::hex << vortex_->snp_req_addr << " tag=" << vortex_->snp_req_tag << " remain=" << (snp_req_size_-1) << std::endl; @@ -238,7 +246,7 @@ void Simulator::eval_snp_bus() { void Simulator::eval_csr_bus() { if (csr_req_active_) { - if (vortex_->csr_io_req_valid && vortex_->csr_io_req_ready) { + if (vortex_->csr_io_req_valid && csr_io_req_ready_) { #ifndef NDEBUG if (vortex_->csr_io_req_rw) std::cout << std::dec << timestamp << ": [sim] CSR Wr Req: core=" << (int)vortex_->csr_io_req_coreid << ", addr=" << std::hex << vortex_->csr_io_req_addr << ", value=" << vortex_->csr_io_req_data << std::endl; diff --git a/hw/simulate/simulator.h b/hw/simulate/simulator.h index 9330c265..a1613d98 100644 --- a/hw/simulate/simulator.h +++ b/hw/simulate/simulator.h @@ -66,6 +66,10 @@ private: std::list dram_rsp_vec_; bool dram_rsp_active_; + bool dram_rsp_ready_; + bool snp_req_ready_; + bool csr_io_req_ready_; + bool snp_req_active_; bool csr_req_active_;