fixed snoop forwarding bug and single bank support
This commit is contained in:
40
hw/rtl/cache/VX_snp_forwarder.v
vendored
40
hw/rtl/cache/VX_snp_forwarder.v
vendored
@@ -34,11 +34,13 @@ module VX_snp_forwarder #(
|
||||
output wire [NUM_REQUESTS-1:0] snp_fwdin_ready
|
||||
);
|
||||
reg [`DRAM_ADDR_WIDTH+SNP_REQ_TAG_WIDTH-1:0] pending_reqs [SNRQ_SIZE-1:0];
|
||||
reg [`REQS_BITS-1:0] pending_cntrs [SNRQ_SIZE-1:0];
|
||||
reg [`LOG2UP(SNRQ_SIZE)-1:0] rd_ptr, wr_ptr;
|
||||
reg [`LOG2UP(SNRQ_SIZE)-1:0] pending_size;
|
||||
reg [`REQS_BITS:0] pending_cntrs [SNRQ_SIZE-1:0];
|
||||
reg [`LOG2UP(SNRQ_SIZE):0] rd_ptr, wr_ptr;
|
||||
reg [`REQS_BITS-1:0] fwdin_sel;
|
||||
wire enqueue, dequeue, empty;
|
||||
|
||||
wire [`LOG2UP(SNRQ_SIZE)-1:0] rd_a, wr_a;
|
||||
|
||||
wire enqueue, dequeue, empty, full;
|
||||
|
||||
wire fwdout_ready;
|
||||
|
||||
@@ -49,47 +51,43 @@ module VX_snp_forwarder #(
|
||||
|
||||
assign fwdout_ready = (& snp_fwdout_ready);
|
||||
|
||||
assign snp_req_ready = (pending_size != `LOG2UP(SNRQ_SIZE)'(SNRQ_SIZE-1)) // not full
|
||||
&& fwdout_ready;
|
||||
assign snp_req_ready = !full && fwdout_ready;
|
||||
|
||||
assign rd_a = rd_ptr[`LOG2UP(SNRQ_SIZE)-1:0];
|
||||
assign wr_a = wr_ptr[`LOG2UP(SNRQ_SIZE)-1:0];
|
||||
|
||||
genvar i;
|
||||
|
||||
for (i = 0; i < NUM_REQUESTS; i++) begin
|
||||
assign snp_fwdout_valid[i] = enqueue && fwdout_ready;
|
||||
assign snp_fwdout_addr[i] = snp_req_addr;
|
||||
assign snp_fwdout_tag[i] = wr_ptr;
|
||||
assign snp_fwdout_tag[i] = wr_a;
|
||||
end
|
||||
|
||||
assign fwdin_ready = snp_rsp_ready;
|
||||
|
||||
assign fwdin_taken = fwdin_valid && fwdin_ready;
|
||||
|
||||
assign snp_rsp_valid = fwdin_taken && (1 == pending_cntrs[fwdin_tag]); // send response
|
||||
assign {snp_rsp_addr, snp_rsp_tag} = pending_reqs[fwdin_tag];
|
||||
|
||||
assign empty = (wr_ptr == rd_ptr);
|
||||
assign full = (wr_a == rd_a) && (wr_ptr[`LOG2UP(SNRQ_SIZE)] != rd_ptr[`LOG2UP(SNRQ_SIZE)]);
|
||||
|
||||
assign enqueue = snp_req_valid && snp_req_ready;
|
||||
assign dequeue = !empty && (0 == pending_cntrs[rd_ptr]);
|
||||
assign dequeue = !empty && (0 == pending_cntrs[rd_a]);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
rd_ptr <= 0;
|
||||
wr_ptr <= 0;
|
||||
pending_size <= 0;
|
||||
rd_ptr <= 0;
|
||||
wr_ptr <= 0;
|
||||
end else begin
|
||||
if (enqueue) begin
|
||||
pending_reqs[wr_ptr] <= {snp_req_addr, snp_req_tag};
|
||||
pending_cntrs[wr_ptr] <= `REQS_BITS'(NUM_REQUESTS);
|
||||
wr_ptr <= wr_ptr + 1;
|
||||
if (!dequeue) begin
|
||||
pending_size <= pending_size + 1;
|
||||
end
|
||||
pending_reqs[wr_a] <= {snp_req_addr, snp_req_tag};
|
||||
pending_cntrs[wr_a] <= NUM_REQUESTS;
|
||||
wr_ptr <= wr_ptr + 1;
|
||||
end
|
||||
if (dequeue) begin
|
||||
rd_ptr <= rd_ptr + 1;
|
||||
if (!enqueue) begin
|
||||
pending_size <= pending_size - 1;
|
||||
end
|
||||
end
|
||||
if (fwdin_taken) begin
|
||||
pending_cntrs[fwdin_tag] <= pending_cntrs[fwdin_tag] - 1;
|
||||
|
||||
Reference in New Issue
Block a user