critical path optimization - fpga fmax @4c = ~212 mhz
This commit is contained in:
@@ -327,7 +327,7 @@
|
|||||||
|
|
||||||
// Size of cache in bytes
|
// Size of cache in bytes
|
||||||
`ifndef SMEM_SIZE
|
`ifndef SMEM_SIZE
|
||||||
`define SMEM_SIZE 4096
|
`define SMEM_SIZE 8192
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// Number of banks
|
// Number of banks
|
||||||
|
|||||||
@@ -307,21 +307,20 @@ module VX_decode #(
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
assign decode_if.valid = ifetch_rsp_if.valid
|
assign decode_if.valid = ifetch_rsp_if.valid;
|
||||||
&& (decode_if.ex_type != `EX_NOP); // skip noop
|
|
||||||
|
|
||||||
assign decode_if.wid = ifetch_rsp_if.wid;
|
assign decode_if.wid = ifetch_rsp_if.wid;
|
||||||
assign decode_if.tmask = ifetch_rsp_if.tmask;
|
assign decode_if.tmask = ifetch_rsp_if.tmask;
|
||||||
assign decode_if.PC = ifetch_rsp_if.PC;
|
assign decode_if.PC = ifetch_rsp_if.PC;
|
||||||
|
|
||||||
assign decode_if.ex_type = is_lsu ? `EX_LSU :
|
assign decode_if.ex_type = is_lsu ? `EX_LSU :
|
||||||
is_csr ? `EX_CSR :
|
is_csr ? `EX_CSR :
|
||||||
is_mul ? `EX_MUL :
|
is_mul ? `EX_MUL :
|
||||||
is_fpu ? `EX_FPU :
|
is_fpu ? `EX_FPU :
|
||||||
is_gpu ? `EX_GPU :
|
is_gpu ? `EX_GPU :
|
||||||
is_br ? `EX_ALU :
|
is_br ? `EX_ALU :
|
||||||
(is_rtype || is_itype || is_lui || is_auipc) ? `EX_ALU :
|
(is_rtype || is_itype || is_lui || is_auipc) ? `EX_ALU :
|
||||||
`EX_NOP;
|
`EX_NOP;
|
||||||
|
|
||||||
assign decode_if.op_type = is_lsu ? `OP_BITS'(lsu_op) :
|
assign decode_if.op_type = is_lsu ? `OP_BITS'(lsu_op) :
|
||||||
is_csr ? `OP_BITS'(csr_op) :
|
is_csr ? `OP_BITS'(csr_op) :
|
||||||
@@ -367,17 +366,17 @@ module VX_decode #(
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
wire decode_fire = decode_if.valid && decode_if.ready;
|
wire decode_fire_unqual = ifetch_rsp_if.valid && decode_if.ready;
|
||||||
|
|
||||||
assign join_if.valid = decode_fire && is_gpu && (gpu_op == `GPU_JOIN);
|
assign join_if.valid = decode_fire_unqual && is_gpu && (gpu_op == `GPU_JOIN);
|
||||||
assign join_if.wid = ifetch_rsp_if.wid;
|
assign join_if.wid = ifetch_rsp_if.wid;
|
||||||
|
|
||||||
assign wstall_if.valid = decode_fire && (is_btype
|
assign wstall_if.valid = decode_fire_unqual && (is_btype
|
||||||
|| is_jal
|
|| is_jal
|
||||||
|| is_jalr
|
|| is_jalr
|
||||||
|| (is_gpu && (gpu_op == `GPU_TMC
|
|| (is_gpu && (gpu_op == `GPU_TMC
|
||||||
|| gpu_op == `GPU_SPLIT
|
|| gpu_op == `GPU_SPLIT
|
||||||
|| gpu_op == `GPU_BAR)));
|
|| gpu_op == `GPU_BAR)));
|
||||||
assign wstall_if.wid = ifetch_rsp_if.wid;
|
assign wstall_if.wid = ifetch_rsp_if.wid;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -11,19 +11,18 @@ module VX_ibuffer #(
|
|||||||
VX_decode_if ibuf_enq_if,
|
VX_decode_if ibuf_enq_if,
|
||||||
|
|
||||||
// outputs
|
// outputs
|
||||||
output wire [`NW_BITS-1:0] deq_wid_next,
|
|
||||||
VX_decode_if ibuf_deq_if
|
VX_decode_if ibuf_deq_if
|
||||||
);
|
);
|
||||||
localparam DATAW = `NUM_THREADS + 32 + `EX_BITS + `OP_BITS + `FRM_BITS + 1 + (`NR_BITS * 4) + 32 + 1 + 1 + `NUM_REGS;
|
localparam DATAW = `NUM_THREADS + 32 + `EX_BITS + `OP_BITS + `FRM_BITS + 1 + (`NR_BITS * 4) + 32 + 1 + 1 + `NUM_REGS;
|
||||||
localparam SIZE = `IBUF_SIZE;
|
localparam SIZE = `IBUF_SIZE;
|
||||||
localparam SIZEW = $clog2(SIZE+1);
|
|
||||||
localparam ADDRW = $clog2(SIZE);
|
localparam ADDRW = $clog2(SIZE);
|
||||||
localparam NWARPSW = $clog2(`NUM_WARPS+1);
|
localparam NWARPSW = $clog2(`NUM_WARPS+1);
|
||||||
|
|
||||||
reg [`NUM_WARPS-1:0][SIZEW-1:0] size_r;
|
reg [`NUM_WARPS-1:0][ADDRW-1:0] used_r;
|
||||||
|
reg [`NUM_WARPS-1:0] full_r, empty_r, sizeMany_r;
|
||||||
|
|
||||||
wire [`NUM_WARPS-1:0] q_full;
|
wire [`NUM_WARPS-1:0] q_full, q_empty;
|
||||||
wire [`NUM_WARPS-1:0][SIZEW-1:0] q_size;
|
wire [`NUM_WARPS-1:0] q_sizeMany;
|
||||||
wire [DATAW-1:0] q_data_in;
|
wire [DATAW-1:0] q_data_in;
|
||||||
wire [`NUM_WARPS-1:0][DATAW-1:0] q_data_prev;
|
wire [`NUM_WARPS-1:0][DATAW-1:0] q_data_prev;
|
||||||
reg [`NUM_WARPS-1:0][DATAW-1:0] q_data_out;
|
reg [`NUM_WARPS-1:0][DATAW-1:0] q_data_out;
|
||||||
@@ -36,15 +35,16 @@ module VX_ibuffer #(
|
|||||||
wire writing = enq_fire && (i == ibuf_enq_if.wid);
|
wire writing = enq_fire && (i == ibuf_enq_if.wid);
|
||||||
wire reading = deq_fire && (i == ibuf_deq_if.wid);
|
wire reading = deq_fire && (i == ibuf_deq_if.wid);
|
||||||
|
|
||||||
wire is_slot0 = (0 == size_r[i]) || ((1 == size_r[i]) && reading);
|
wire is_slot0 = (0 == used_r[i]) || ((1 == used_r[i]) && reading);
|
||||||
|
|
||||||
wire push = writing && !is_slot0;
|
wire push = writing && !is_slot0;
|
||||||
wire pop = reading && (size_r[i] != 1);
|
wire pop = reading && sizeMany_r[i];
|
||||||
|
|
||||||
VX_generic_queue #(
|
VX_generic_queue #(
|
||||||
.DATAW (DATAW),
|
.DATAW (DATAW),
|
||||||
.SIZE (SIZE),
|
.SIZE (SIZE),
|
||||||
.FASTRAM (1)
|
.BUFFERED (1),
|
||||||
|
.FASTRAM (1)
|
||||||
) queue (
|
) queue (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (reset),
|
.reset (reset),
|
||||||
@@ -59,26 +59,43 @@ module VX_ibuffer #(
|
|||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
size_r[i] <= 0;
|
used_r[i] <= 0;
|
||||||
|
full_r[i] <= 0;
|
||||||
|
empty_r[i] <= 1;
|
||||||
|
sizeMany_r[i] <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (writing && !reading) begin
|
if (writing && !reading) begin
|
||||||
size_r[i] <= size_r[i] + SIZEW'(1);
|
empty_r[i] <= 0;
|
||||||
|
if (used_r[i] == ADDRW'(SIZE-1)) begin
|
||||||
|
full_r[i] <= 1;
|
||||||
|
end
|
||||||
|
if (used_r[i] == 1) begin
|
||||||
|
sizeMany_r[i] <= 1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if (reading && !writing) begin
|
if (reading && !writing) begin
|
||||||
size_r[i] <= size_r[i] - SIZEW'(1);
|
full_r[i] <= 0;
|
||||||
|
if (used_r[i] == ADDRW'(1)) begin
|
||||||
|
empty_r[i] <= 1;
|
||||||
|
end
|
||||||
|
if (used_r[i] == ADDRW'(2)) begin
|
||||||
|
sizeMany_r[i] <= 0;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
used_r[i] <= used_r[i] + ADDRW'($signed(2'(writing) - 2'(reading)));
|
||||||
end
|
end
|
||||||
|
|
||||||
if (writing && is_slot0) begin
|
if (writing && is_slot0) begin
|
||||||
q_data_out[i] <= q_data_in;
|
q_data_out[i] <= q_data_in;
|
||||||
end
|
end
|
||||||
if (reading && (size_r[i] != 1)) begin
|
if (pop) begin
|
||||||
q_data_out[i] <= q_data_prev[i];
|
q_data_out[i] <= q_data_prev[i];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign q_full[i] = (size_r[i] == SIZE);
|
assign q_full[i] = full_r[i];
|
||||||
assign q_size[i] = size_r[i];
|
assign q_empty[i] = empty_r[i];
|
||||||
|
assign q_sizeMany[i] = sizeMany_r[i];
|
||||||
end
|
end
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@@ -93,7 +110,7 @@ module VX_ibuffer #(
|
|||||||
always @(*) begin
|
always @(*) begin
|
||||||
valid_table_n = valid_table;
|
valid_table_n = valid_table;
|
||||||
if (deq_fire) begin
|
if (deq_fire) begin
|
||||||
valid_table_n[deq_wid] = (q_size[deq_wid] != SIZEW'(1));
|
valid_table_n[deq_wid] = q_sizeMany[deq_wid];
|
||||||
end
|
end
|
||||||
if (enq_fire) begin
|
if (enq_fire) begin
|
||||||
valid_table_n[ibuf_enq_if.wid] = 1;
|
valid_table_n[ibuf_enq_if.wid] = 1;
|
||||||
@@ -103,24 +120,24 @@ module VX_ibuffer #(
|
|||||||
// schedule the next instruction to issue
|
// schedule the next instruction to issue
|
||||||
// do round-robin when multiple warps are active
|
// do round-robin when multiple warps are active
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
deq_valid_n = 0;
|
deq_valid_n = 0;
|
||||||
deq_wid_n = 'x;
|
deq_wid_n = 'x;
|
||||||
deq_instr_n = 'x;
|
deq_instr_n = 'x;
|
||||||
|
|
||||||
schedule_table_n = schedule_table;
|
schedule_table_n = schedule_table;
|
||||||
|
|
||||||
if (0 == num_warps) begin
|
if (0 == num_warps) begin
|
||||||
deq_valid_n = enq_fire;
|
deq_valid_n = enq_fire;
|
||||||
deq_wid_n = ibuf_enq_if.wid;
|
deq_wid_n = ibuf_enq_if.wid;
|
||||||
deq_instr_n = q_data_in;
|
deq_instr_n = q_data_in;
|
||||||
end else if ((1 == num_warps) || freeze) begin
|
end else if ((1 == num_warps) || freeze) begin
|
||||||
deq_valid_n = (!deq_fire || (q_size[deq_wid] != SIZEW'(1))) || enq_fire;
|
deq_valid_n = (!deq_fire || q_sizeMany[deq_wid]) || enq_fire;
|
||||||
deq_wid_n = (!deq_fire || (q_size[deq_wid] != SIZEW'(1))) ? deq_wid : ibuf_enq_if.wid;
|
deq_wid_n = (!deq_fire || q_sizeMany[deq_wid]) ? deq_wid : ibuf_enq_if.wid;
|
||||||
deq_instr_n = deq_fire ? ((q_size[deq_wid] != SIZEW'(1)) ? q_data_prev[deq_wid] : q_data_in) : q_data_out[deq_wid];
|
deq_instr_n = deq_fire ? (q_sizeMany[deq_wid] ? q_data_prev[deq_wid] : q_data_in) : q_data_out[deq_wid];
|
||||||
end else begin
|
end else begin
|
||||||
|
deq_valid_n = (| schedule_table_n);
|
||||||
for (integer i = 0; i < `NUM_WARPS; i++) begin
|
for (integer i = 0; i < `NUM_WARPS; i++) begin
|
||||||
if (schedule_table_n[i]) begin
|
if (schedule_table_n[i]) begin
|
||||||
deq_valid_n = 1;
|
|
||||||
deq_wid_n = `NW_BITS'(i);
|
deq_wid_n = `NW_BITS'(i);
|
||||||
deq_instr_n = q_data_out[i];
|
deq_instr_n = q_data_out[i];
|
||||||
schedule_table_n[i] = 0;
|
schedule_table_n[i] = 0;
|
||||||
@@ -130,8 +147,8 @@ module VX_ibuffer #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wire warp_added = enq_fire && (0 == q_size[ibuf_enq_if.wid]);
|
wire warp_added = enq_fire && q_empty[ibuf_enq_if.wid];
|
||||||
wire warp_removed = deq_fire && ~(enq_fire && ibuf_enq_if.wid == deq_wid) && ~(q_size[deq_wid] != SIZEW'(1));
|
wire warp_removed = deq_fire && ~(enq_fire && ibuf_enq_if.wid == deq_wid) && ~q_sizeMany[deq_wid];
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
@@ -162,23 +179,21 @@ module VX_ibuffer #(
|
|||||||
`ifdef VERILATOR
|
`ifdef VERILATOR
|
||||||
/*if (enq_fire || deq_fire || deq_valid) begin
|
/*if (enq_fire || deq_fire || deq_valid) begin
|
||||||
$display("*** %t: cur=%b(%0d), nxt=%b(%0d), enq=%b(%0d), deq=%b(%0d), nw=%0d(%0d,%0d,%0d,%0d), sched=%b, sched_n=%b",
|
$display("*** %t: cur=%b(%0d), nxt=%b(%0d), enq=%b(%0d), deq=%b(%0d), nw=%0d(%0d,%0d,%0d,%0d), sched=%b, sched_n=%b",
|
||||||
$time, deq_valid, deq_wid, deq_valid_n, deq_wid_n, enq_fire, ibuf_enq_if.wid, deq_fire, ibuf_deq_if.wid, num_warps, size_r[0], size_r[1], size_r[2], size_r[3], schedule_table, schedule_table_n);
|
$time, deq_valid, deq_wid, deq_valid_n, deq_wid_n, enq_fire, ibuf_enq_if.wid, deq_fire, ibuf_deq_if.wid, num_warps, used_r[0], used_r[1], used_r[2], used_r[3], schedule_table, schedule_table_n);
|
||||||
end*/
|
end*/
|
||||||
begin // verify 'num_warps'
|
begin // verify 'num_warps'
|
||||||
integer nw = 0;
|
integer nw = 0;
|
||||||
for (integer i = 0; i < `NUM_WARPS; i++) begin
|
for (integer i = 0; i < `NUM_WARPS; i++) begin
|
||||||
nw += 32'(q_size[i] != 0);
|
nw += 32'(!q_empty[i]);
|
||||||
end
|
end
|
||||||
assert(nw == 32'(num_warps)) else $error("%t: error: invalid num_warps: nw=%0d, ref=%0d", $time, num_warps, nw);
|
assert(nw == 32'(num_warps)) else $error("%t: error: invalid num_warps: nw=%0d, ref=%0d", $time, num_warps, nw);
|
||||||
assert(~deq_valid || (q_size[deq_wid] != 0)) else $error("%t: error: invalid schedule: wid=%0d", $time, deq_wid);
|
assert(~deq_valid || !q_empty[deq_wid]) else $error("%t: error: invalid schedule: wid=%0d", $time, deq_wid);
|
||||||
assert(~deq_fire || (q_size[deq_wid] != 0)) else $error("%t: error: invalid dequeu: wid=%0d", $time, deq_wid);
|
assert(~deq_fire || !q_empty[deq_wid]) else $error("%t: error: invalid dequeu: wid=%0d", $time, deq_wid);
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign deq_wid_next = deq_wid_n;
|
|
||||||
|
|
||||||
assign ibuf_enq_if.ready = ~q_full[ibuf_enq_if.wid];
|
assign ibuf_enq_if.ready = ~q_full[ibuf_enq_if.wid];
|
||||||
assign q_data_in = {ibuf_enq_if.tmask,
|
assign q_data_in = {ibuf_enq_if.tmask,
|
||||||
ibuf_enq_if.PC,
|
ibuf_enq_if.PC,
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ module VX_ipdom_stack #(
|
|||||||
VX_dp_ram #(
|
VX_dp_ram #(
|
||||||
.DATAW(WIDTH * 2),
|
.DATAW(WIDTH * 2),
|
||||||
.SIZE(DEPTH),
|
.SIZE(DEPTH),
|
||||||
.RWCHECK(0)
|
.RWCHECK(1),
|
||||||
|
.FASTRAM(1)
|
||||||
) store (
|
) store (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.waddr(wr_ptr),
|
.waddr(wr_ptr),
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ module VX_issue #(
|
|||||||
VX_gpr_rsp_if gpr_rsp_if();
|
VX_gpr_rsp_if gpr_rsp_if();
|
||||||
|
|
||||||
wire scoreboard_delay;
|
wire scoreboard_delay;
|
||||||
wire [`NW_BITS-1:0] deq_wid_next;
|
|
||||||
|
|
||||||
VX_ibuffer #(
|
VX_ibuffer #(
|
||||||
.CORE_ID(CORE_ID)
|
.CORE_ID(CORE_ID)
|
||||||
@@ -37,7 +36,6 @@ module VX_issue #(
|
|||||||
.reset (reset),
|
.reset (reset),
|
||||||
.freeze (1'b0),
|
.freeze (1'b0),
|
||||||
.ibuf_enq_if (decode_if),
|
.ibuf_enq_if (decode_if),
|
||||||
.deq_wid_next (deq_wid_next),
|
|
||||||
.ibuf_deq_if (ibuf_deq_if)
|
.ibuf_deq_if (ibuf_deq_if)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -48,8 +46,6 @@ module VX_issue #(
|
|||||||
.reset (reset),
|
.reset (reset),
|
||||||
.ibuf_deq_if (ibuf_deq_if),
|
.ibuf_deq_if (ibuf_deq_if),
|
||||||
.writeback_if (writeback_if),
|
.writeback_if (writeback_if),
|
||||||
.deq_wid_next (deq_wid_next),
|
|
||||||
.exe_delay (~execute_if.ready),
|
|
||||||
.delay (scoreboard_delay)
|
.delay (scoreboard_delay)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -95,6 +91,9 @@ module VX_issue #(
|
|||||||
.gpu_req_if (gpu_req_if)
|
.gpu_req_if (gpu_req_if)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// issue the instruction
|
||||||
|
assign ibuf_deq_if.ready = !scoreboard_delay && execute_if.ready;
|
||||||
|
|
||||||
`SCOPE_ASSIGN (issue_fire, ibuf_deq_if.valid && ibuf_deq_if.ready);
|
`SCOPE_ASSIGN (issue_fire, ibuf_deq_if.valid && ibuf_deq_if.ready);
|
||||||
`SCOPE_ASSIGN (issue_wid, ibuf_deq_if.wid);
|
`SCOPE_ASSIGN (issue_wid, ibuf_deq_if.wid);
|
||||||
`SCOPE_ASSIGN (issue_tmask, ibuf_deq_if.tmask);
|
`SCOPE_ASSIGN (issue_tmask, ibuf_deq_if.tmask);
|
||||||
@@ -123,8 +122,8 @@ module VX_issue #(
|
|||||||
`SCOPE_ASSIGN (writeback_data, writeback_if.data);
|
`SCOPE_ASSIGN (writeback_data, writeback_if.data);
|
||||||
|
|
||||||
`ifdef PERF_ENABLE
|
`ifdef PERF_ENABLE
|
||||||
reg [63:0] perf_ibf_stalls ;
|
reg [63:0] perf_ibf_stalls;
|
||||||
reg [63:0] perf_scb_stalls ;
|
reg [63:0] perf_scb_stalls;
|
||||||
reg [63:0] perf_alu_stalls;
|
reg [63:0] perf_alu_stalls;
|
||||||
reg [63:0] perf_lsu_stalls;
|
reg [63:0] perf_lsu_stalls;
|
||||||
reg [63:0] perf_csr_stalls;
|
reg [63:0] perf_csr_stalls;
|
||||||
|
|||||||
@@ -3,21 +3,19 @@
|
|||||||
module VX_scoreboard #(
|
module VX_scoreboard #(
|
||||||
parameter CORE_ID = 0
|
parameter CORE_ID = 0
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
|
|
||||||
VX_decode_if ibuf_deq_if,
|
VX_decode_if ibuf_deq_if,
|
||||||
VX_writeback_if writeback_if,
|
VX_writeback_if writeback_if,
|
||||||
input wire [`NW_BITS-1:0] deq_wid_next,
|
output wire delay
|
||||||
input wire exe_delay,
|
|
||||||
|
|
||||||
output wire delay
|
|
||||||
);
|
);
|
||||||
reg [`NUM_THREADS-1:0] inuse_registers [(`NUM_WARPS * `NUM_REGS)-1:0];
|
reg [`NUM_THREADS-1:0] inuse_registers [(`NUM_WARPS * `NUM_REGS)-1:0];
|
||||||
reg [`NUM_WARPS-1:0][`NUM_REGS-1:0] inuse_reg_mask, inuse_reg_mask_n;
|
reg [`NUM_WARPS-1:0][`NUM_REGS-1:0] inuse_reg_mask;
|
||||||
reg [`NUM_REGS-1:0] deq_used_regs;
|
wire [`NUM_REGS-1:0] inuse_regs;
|
||||||
|
wire [`NUM_THREADS-1:0] inuse_registers_n;
|
||||||
|
|
||||||
wire [`NUM_REGS-1:0] inuse_regs = deq_used_regs & ibuf_deq_if.used_regs;
|
assign inuse_regs = inuse_reg_mask[ibuf_deq_if.wid] & ibuf_deq_if.used_regs;
|
||||||
|
|
||||||
assign delay = (| inuse_regs);
|
assign delay = (| inuse_regs);
|
||||||
|
|
||||||
@@ -25,17 +23,7 @@ module VX_scoreboard #(
|
|||||||
|
|
||||||
wire release_reg = writeback_if.valid && writeback_if.ready;
|
wire release_reg = writeback_if.valid && writeback_if.ready;
|
||||||
|
|
||||||
wire [`NUM_THREADS-1:0] inuse_registers_n = inuse_registers[{writeback_if.wid, writeback_if.rd}] & ~writeback_if.tmask;
|
assign inuse_registers_n = inuse_registers[{writeback_if.wid, writeback_if.rd}] & ~writeback_if.tmask;
|
||||||
|
|
||||||
always @(*) begin
|
|
||||||
inuse_reg_mask_n = inuse_reg_mask;
|
|
||||||
if (reserve_reg) begin
|
|
||||||
inuse_reg_mask_n[ibuf_deq_if.wid][ibuf_deq_if.rd] = 1;
|
|
||||||
end
|
|
||||||
if (release_reg) begin
|
|
||||||
inuse_reg_mask_n[writeback_if.wid][writeback_if.rd] = (| inuse_registers_n);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
@@ -48,28 +36,24 @@ module VX_scoreboard #(
|
|||||||
end else begin
|
end else begin
|
||||||
if (reserve_reg) begin
|
if (reserve_reg) begin
|
||||||
inuse_registers[{ibuf_deq_if.wid, ibuf_deq_if.rd}] <= ibuf_deq_if.tmask;
|
inuse_registers[{ibuf_deq_if.wid, ibuf_deq_if.rd}] <= ibuf_deq_if.tmask;
|
||||||
|
inuse_reg_mask[ibuf_deq_if.wid][ibuf_deq_if.rd] <= 1;
|
||||||
end
|
end
|
||||||
if (release_reg) begin
|
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",
|
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);
|
$time, CORE_ID, writeback_if.wid, writeback_if.PC, writeback_if.rd);
|
||||||
inuse_registers[{writeback_if.wid, writeback_if.rd}] <= inuse_registers_n;
|
inuse_registers[{writeback_if.wid, writeback_if.rd}] <= inuse_registers_n;
|
||||||
|
inuse_reg_mask[writeback_if.wid][writeback_if.rd] <= (| inuse_registers_n);
|
||||||
end
|
end
|
||||||
inuse_reg_mask <= inuse_reg_mask_n;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
deq_used_regs <= inuse_reg_mask_n[deq_wid_next];
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// issue the instruction
|
|
||||||
assign ibuf_deq_if.ready = ~(delay || exe_delay);
|
|
||||||
|
|
||||||
`ifdef DBG_PRINT_PIPELINE
|
`ifdef DBG_PRINT_PIPELINE
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (ibuf_deq_if.valid && ~ibuf_deq_if.ready) begin
|
if (ibuf_deq_if.valid && ~ibuf_deq_if.ready) begin
|
||||||
$display("%t: core%0d-stall: wid=%0d, PC=%0h, rd=%0d, wb=%0d, inuse=%b%b%b%b, exe=%b",
|
$display("%t: core%0d-stall: wid=%0d, PC=%0h, rd=%0d, wb=%0d, inuse=%b%b%b%b",
|
||||||
$time, CORE_ID, ibuf_deq_if.wid, ibuf_deq_if.PC, ibuf_deq_if.rd, ibuf_deq_if.wb,
|
$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);
|
inuse_regs[ibuf_deq_if.rd], inuse_regs[ibuf_deq_if.rs1], inuse_regs[ibuf_deq_if.rs2], inuse_regs[ibuf_deq_if.rs3]);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
@@ -80,9 +64,9 @@ module VX_scoreboard #(
|
|||||||
stall_ctr <= 0;
|
stall_ctr <= 0;
|
||||||
end else if (ibuf_deq_if.valid && ~ibuf_deq_if.ready) begin
|
end else if (ibuf_deq_if.valid && ~ibuf_deq_if.ready) begin
|
||||||
stall_ctr <= stall_ctr + 1;
|
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",
|
assert(stall_ctr < 100000) else $error("*** %t: core%0d-stalled: wid=%0d, PC=%0h, rd=%0d, wb=%0d, inuse=%b%b%b%b",
|
||||||
$time, CORE_ID, ibuf_deq_if.wid, ibuf_deq_if.PC, ibuf_deq_if.rd, ibuf_deq_if.wb,
|
$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);
|
inuse_regs[ibuf_deq_if.rd], inuse_regs[ibuf_deq_if.rs1], inuse_regs[ibuf_deq_if.rs2], inuse_regs[ibuf_deq_if.rs3]);
|
||||||
end else if (ibuf_deq_if.valid && ibuf_deq_if.ready) begin
|
end else if (ibuf_deq_if.valid && ibuf_deq_if.ready) begin
|
||||||
stall_ctr <= 0;
|
stall_ctr <= 0;
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ module VX_writeback #(
|
|||||||
VX_writeback_if writeback_if
|
VX_writeback_if writeback_if
|
||||||
);
|
);
|
||||||
wire alu_valid = alu_commit_if.valid && alu_commit_if.wb;
|
wire alu_valid = alu_commit_if.valid && alu_commit_if.wb;
|
||||||
wire ld_valid = ld_commit_if.valid /*&& ld_commit_if.wb*/;
|
wire ld_valid = ld_commit_if.valid && ld_commit_if.wb;
|
||||||
wire csr_valid = csr_commit_if.valid && csr_commit_if.wb;
|
wire csr_valid = csr_commit_if.valid && csr_commit_if.wb;
|
||||||
wire mul_valid = mul_commit_if.valid && mul_commit_if.wb;
|
wire mul_valid = mul_commit_if.valid && mul_commit_if.wb;
|
||||||
wire fpu_valid = fpu_commit_if.valid && fpu_commit_if.wb;
|
wire fpu_valid = fpu_commit_if.valid && fpu_commit_if.wb;
|
||||||
|
|||||||
33
hw/rtl/cache/VX_cache.v
vendored
33
hw/rtl/cache/VX_cache.v
vendored
@@ -91,6 +91,11 @@ module VX_cache #(
|
|||||||
|
|
||||||
wire [NUM_BANKS-1:0] per_bank_core_req_valid;
|
wire [NUM_BANKS-1:0] per_bank_core_req_valid;
|
||||||
wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_req_tid;
|
wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_req_tid;
|
||||||
|
wire [NUM_BANKS-1:0] per_bank_core_req_rw;
|
||||||
|
wire [NUM_BANKS-1:0][WORD_SIZE-1:0] per_bank_core_req_byteen;
|
||||||
|
wire [NUM_BANKS-1:0][`WORD_ADDR_WIDTH-1:0] per_bank_core_req_addr;
|
||||||
|
wire [NUM_BANKS-1:0][CORE_TAG_WIDTH-1:0] per_bank_core_req_tag;
|
||||||
|
wire [NUM_BANKS-1:0][`WORD_WIDTH-1:0] per_bank_core_req_data;
|
||||||
wire [NUM_BANKS-1:0] per_bank_core_req_ready;
|
wire [NUM_BANKS-1:0] per_bank_core_req_ready;
|
||||||
|
|
||||||
wire [NUM_BANKS-1:0] per_bank_core_rsp_valid;
|
wire [NUM_BANKS-1:0] per_bank_core_rsp_valid;
|
||||||
@@ -122,7 +127,8 @@ module VX_cache #(
|
|||||||
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
.BANK_LINE_SIZE (BANK_LINE_SIZE),
|
||||||
.NUM_BANKS (NUM_BANKS),
|
.NUM_BANKS (NUM_BANKS),
|
||||||
.WORD_SIZE (WORD_SIZE),
|
.WORD_SIZE (WORD_SIZE),
|
||||||
.NUM_REQS (NUM_REQS)
|
.NUM_REQS (NUM_REQS),
|
||||||
|
.CORE_TAG_WIDTH (CORE_TAG_WIDTH)
|
||||||
) cache_core_req_bank_sel (
|
) cache_core_req_bank_sel (
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (reset),
|
.reset (reset),
|
||||||
@@ -132,11 +138,20 @@ module VX_cache #(
|
|||||||
`UNUSED_PIN (bank_stalls),
|
`UNUSED_PIN (bank_stalls),
|
||||||
`endif
|
`endif
|
||||||
.core_req_valid (core_req_valid),
|
.core_req_valid (core_req_valid),
|
||||||
|
.core_req_rw (core_req_rw),
|
||||||
|
.core_req_byteen(core_req_byteen),
|
||||||
.core_req_addr (core_req_addr),
|
.core_req_addr (core_req_addr),
|
||||||
|
.core_req_data (core_req_data),
|
||||||
|
.core_req_tag (core_req_tag),
|
||||||
.core_req_ready (core_req_ready),
|
.core_req_ready (core_req_ready),
|
||||||
.per_bank_valid (per_bank_core_req_valid),
|
.per_bank_core_req_valid (per_bank_core_req_valid),
|
||||||
.per_bank_tid (per_bank_core_req_tid),
|
.per_bank_core_req_tid (per_bank_core_req_tid),
|
||||||
.per_bank_ready (per_bank_core_req_ready)
|
.per_bank_core_req_rw (per_bank_core_req_rw),
|
||||||
|
.per_bank_core_req_byteen(per_bank_core_req_byteen),
|
||||||
|
.per_bank_core_req_addr (per_bank_core_req_addr),
|
||||||
|
.per_bank_core_req_tag (per_bank_core_req_tag),
|
||||||
|
.per_bank_core_req_data (per_bank_core_req_data),
|
||||||
|
.per_bank_core_req_ready (per_bank_core_req_ready)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign dram_req_tag = dram_req_addr;
|
assign dram_req_tag = dram_req_addr;
|
||||||
@@ -179,11 +194,11 @@ module VX_cache #(
|
|||||||
// Core Req
|
// Core Req
|
||||||
assign curr_bank_core_req_valid = per_bank_core_req_valid[i];
|
assign curr_bank_core_req_valid = per_bank_core_req_valid[i];
|
||||||
assign curr_bank_core_req_tid = per_bank_core_req_tid[i];
|
assign curr_bank_core_req_tid = per_bank_core_req_tid[i];
|
||||||
assign curr_bank_core_req_addr = core_req_addr[per_bank_core_req_tid[i]];
|
assign curr_bank_core_req_addr = per_bank_core_req_addr[i];
|
||||||
assign curr_bank_core_req_rw = core_req_rw[per_bank_core_req_tid[i]];
|
assign curr_bank_core_req_rw = per_bank_core_req_rw[i];
|
||||||
assign curr_bank_core_req_byteen = core_req_byteen[per_bank_core_req_tid[i]];
|
assign curr_bank_core_req_byteen = per_bank_core_req_byteen[i];
|
||||||
assign curr_bank_core_req_data = core_req_data[per_bank_core_req_tid[i]];
|
assign curr_bank_core_req_data = per_bank_core_req_data[i];
|
||||||
assign curr_bank_core_req_tag = core_req_tag[per_bank_core_req_tid[i]];
|
assign curr_bank_core_req_tag = per_bank_core_req_tag[i];
|
||||||
assign per_bank_core_req_ready[i] = curr_bank_core_req_ready;
|
assign per_bank_core_req_ready[i] = curr_bank_core_req_ready;
|
||||||
|
|
||||||
// Core WB
|
// Core WB
|
||||||
|
|||||||
106
hw/rtl/cache/VX_cache_core_req_bank_sel.v
vendored
106
hw/rtl/cache/VX_cache_core_req_bank_sel.v
vendored
@@ -8,48 +8,80 @@ module VX_cache_core_req_bank_sel #(
|
|||||||
// Number of banks
|
// Number of banks
|
||||||
parameter NUM_BANKS = 1,
|
parameter NUM_BANKS = 1,
|
||||||
// Number of Word requests per cycle
|
// Number of Word requests per cycle
|
||||||
parameter NUM_REQS = 1
|
parameter NUM_REQS = 1,
|
||||||
|
// core request tag size
|
||||||
|
parameter CORE_TAG_WIDTH = 1
|
||||||
) (
|
) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
input wire [NUM_REQS-1:0] core_req_valid,
|
|
||||||
input wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
|
output wire [63:0] bank_stalls,
|
||||||
output wire [NUM_REQS-1:0] core_req_ready,
|
|
||||||
output wire [NUM_BANKS-1:0] per_bank_valid,
|
input wire [NUM_REQS-1:0] core_req_valid,
|
||||||
output wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_tid,
|
input wire [NUM_REQS-1:0] core_req_rw,
|
||||||
input wire [NUM_BANKS-1:0] per_bank_ready,
|
input wire [NUM_REQS-1:0][WORD_SIZE-1:0] core_req_byteen,
|
||||||
output wire [63:0] bank_stalls
|
input wire [NUM_REQS-1:0][`WORD_ADDR_WIDTH-1:0] core_req_addr,
|
||||||
|
input wire [NUM_REQS-1:0][`WORD_WIDTH-1:0] core_req_data,
|
||||||
|
input wire [NUM_REQS-1:0][CORE_TAG_WIDTH-1:0] core_req_tag,
|
||||||
|
output wire [NUM_REQS-1:0] core_req_ready,
|
||||||
|
|
||||||
|
output wire [NUM_BANKS-1:0] per_bank_core_req_valid,
|
||||||
|
output wire [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_req_tid,
|
||||||
|
output wire [NUM_BANKS-1:0] per_bank_core_req_rw,
|
||||||
|
output wire [NUM_BANKS-1:0][WORD_SIZE-1:0] per_bank_core_req_byteen,
|
||||||
|
output wire [NUM_BANKS-1:0][`WORD_ADDR_WIDTH-1:0] per_bank_core_req_addr,
|
||||||
|
output wire [NUM_BANKS-1:0][CORE_TAG_WIDTH-1:0] per_bank_core_req_tag,
|
||||||
|
output wire [NUM_BANKS-1:0][`WORD_WIDTH-1:0] per_bank_core_req_data,
|
||||||
|
input wire [NUM_BANKS-1:0] per_bank_core_req_ready
|
||||||
);
|
);
|
||||||
if (NUM_BANKS > 1) begin
|
if (NUM_BANKS > 1) begin
|
||||||
reg [NUM_BANKS-1:0] per_bank_valid_r;
|
|
||||||
reg [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_tid_r;
|
reg [NUM_BANKS-1:0] per_bank_core_req_valid_r;
|
||||||
reg [NUM_REQS-1:0] core_req_ready_r;
|
reg [NUM_BANKS-1:0][`REQS_BITS-1:0] per_bank_core_req_tid_r;
|
||||||
reg [NUM_BANKS-1:0] core_req_sel_r;
|
reg [NUM_BANKS-1:0] per_bank_core_req_rw_r;
|
||||||
wire [NUM_REQS-1:0][`BANK_BITS-1:0] core_req_bid;
|
reg [NUM_BANKS-1:0][WORD_SIZE-1:0] per_bank_core_req_byteen_r;
|
||||||
|
reg [NUM_BANKS-1:0][`WORD_ADDR_WIDTH-1:0] per_bank_core_req_addr_r;
|
||||||
|
reg [NUM_BANKS-1:0][CORE_TAG_WIDTH-1:0] per_bank_core_req_tag_r;
|
||||||
|
reg [NUM_BANKS-1:0][`WORD_WIDTH-1:0] per_bank_core_req_data_r;
|
||||||
|
reg [NUM_REQS-1:0] core_req_ready_r;
|
||||||
|
reg [NUM_BANKS-1:0] core_req_sel_r;
|
||||||
|
wire [NUM_REQS-1:0][`BANK_BITS-1:0] core_req_bid;
|
||||||
|
|
||||||
for (genvar i = 0; i < NUM_REQS; ++i) begin
|
for (genvar i = 0; i < NUM_REQS; ++i) begin
|
||||||
assign core_req_bid[i] = core_req_addr[i][`BANK_SELECT_ADDR_RNG];
|
assign core_req_bid[i] = core_req_addr[i][`BANK_SELECT_ADDR_RNG];
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
per_bank_valid_r = 0;
|
per_bank_core_req_valid_r = 0;
|
||||||
per_bank_tid_r = 'x;
|
per_bank_core_req_tid_r = 'x;
|
||||||
|
per_bank_core_req_rw_r = 'x;
|
||||||
|
per_bank_core_req_byteen_r= 'x;
|
||||||
|
per_bank_core_req_addr_r = 'x;
|
||||||
|
per_bank_core_req_tag_r = 'x;
|
||||||
|
per_bank_core_req_data_r = 'x;
|
||||||
|
|
||||||
for (integer i = NUM_REQS-1; i >= 0; --i) begin
|
for (integer i = NUM_REQS-1; i >= 0; --i) begin
|
||||||
if (core_req_valid[i]) begin
|
if (core_req_valid[i]) begin
|
||||||
per_bank_valid_r[core_req_bid[i]] = 1;
|
per_bank_core_req_valid_r[core_req_bid[i]] = 1;
|
||||||
per_bank_tid_r[core_req_bid[i]] = `REQS_BITS'(i);
|
per_bank_core_req_tid_r[core_req_bid[i]] = `REQS_BITS'(i);
|
||||||
|
per_bank_core_req_rw_r[core_req_bid[i]] = core_req_rw[i];
|
||||||
|
per_bank_core_req_byteen_r[core_req_bid[i]]= core_req_byteen[i];
|
||||||
|
per_bank_core_req_addr_r[core_req_bid[i]] = core_req_addr[i];
|
||||||
|
per_bank_core_req_tag_r[core_req_bid[i]] = core_req_tag[i];
|
||||||
|
per_bank_core_req_data_r[core_req_bid[i]] = core_req_data[i];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
core_req_ready_r = 0;
|
core_req_ready_r = 0;
|
||||||
core_req_sel_r = 0;
|
core_req_sel_r = 0;
|
||||||
|
|
||||||
for (integer j = 0; j < NUM_BANKS; ++j) begin
|
for (integer j = 0; j < NUM_BANKS; ++j) begin
|
||||||
for (integer i = 0; i < NUM_REQS; ++i) begin
|
for (integer i = 0; i < NUM_REQS; ++i) begin
|
||||||
if (core_req_valid[i] && (core_req_bid[i] == `BANK_BITS'(j))) begin
|
if (core_req_valid[i] && (core_req_bid[i] == `BANK_BITS'(j))) begin
|
||||||
core_req_ready_r[i] = per_bank_ready[j];
|
core_req_ready_r[i] = per_bank_core_req_ready[j];
|
||||||
core_req_sel_r[i] = 1;
|
core_req_sel_r[i] = 1;
|
||||||
break;
|
break;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -65,20 +97,30 @@ module VX_cache_core_req_bank_sel #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign per_bank_valid = per_bank_valid_r;
|
assign bank_stalls = bank_stalls_r;
|
||||||
assign per_bank_tid = per_bank_tid_r;
|
assign per_bank_core_req_valid = per_bank_core_req_valid_r;
|
||||||
assign core_req_ready = core_req_ready_r;
|
assign per_bank_core_req_tid = per_bank_core_req_tid_r;
|
||||||
assign bank_stalls = bank_stalls_r;
|
assign per_bank_core_req_rw = per_bank_core_req_rw_r;
|
||||||
|
assign per_bank_core_req_byteen = per_bank_core_req_byteen_r;
|
||||||
|
assign per_bank_core_req_addr = per_bank_core_req_addr_r;
|
||||||
|
assign per_bank_core_req_tag = per_bank_core_req_tag_r;
|
||||||
|
assign per_bank_core_req_data = per_bank_core_req_data_r;
|
||||||
|
assign core_req_ready = core_req_ready_r;
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
|
|
||||||
`UNUSED_VAR (clk)
|
`UNUSED_VAR (clk)
|
||||||
`UNUSED_VAR (reset)
|
`UNUSED_VAR (reset)
|
||||||
`UNUSED_VAR (core_req_valid)
|
assign bank_stalls = 0;
|
||||||
`UNUSED_VAR (core_req_addr)
|
assign per_bank_core_req_valid = core_req_valid;
|
||||||
assign per_bank_valid = core_req_valid;
|
assign per_bank_core_req_tid[0] = 0;
|
||||||
assign per_bank_tid = 0;
|
assign per_bank_core_req_rw[0] = core_req_rw;
|
||||||
assign core_req_ready[0] = per_bank_ready;
|
assign per_bank_core_req_byteen[0] = core_req_byteen;
|
||||||
assign bank_stalls = 0;
|
assign per_bank_core_req_addr[0] = core_req_addr;
|
||||||
|
assign per_bank_core_req_tag[0] = core_req_tag;
|
||||||
|
assign per_bank_core_req_data[0] = core_req_data;
|
||||||
|
assign core_req_ready[0] = per_bank_core_req_ready;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
6
hw/rtl/cache/VX_cache_core_rsp_merge.v
vendored
6
hw/rtl/cache/VX_cache_core_rsp_merge.v
vendored
@@ -37,7 +37,6 @@ module VX_cache_core_rsp_merge #(
|
|||||||
if (CORE_TAG_ID_BITS != 0) begin
|
if (CORE_TAG_ID_BITS != 0) begin
|
||||||
|
|
||||||
reg [CORE_TAG_WIDTH-1:0] core_rsp_tag_unqual;
|
reg [CORE_TAG_WIDTH-1:0] core_rsp_tag_unqual;
|
||||||
reg [CORE_TAG_ID_BITS-1:0] sel_tag_id;
|
|
||||||
reg core_rsp_valid_unaual_any;
|
reg core_rsp_valid_unaual_any;
|
||||||
wire core_rsp_ready_unqual;
|
wire core_rsp_ready_unqual;
|
||||||
|
|
||||||
@@ -48,19 +47,16 @@ module VX_cache_core_rsp_merge #(
|
|||||||
core_rsp_data_unqual = 'x;
|
core_rsp_data_unqual = 'x;
|
||||||
core_rsp_bank_select = 0;
|
core_rsp_bank_select = 0;
|
||||||
|
|
||||||
sel_tag_id = 'x;
|
|
||||||
|
|
||||||
for (integer i = 0; i < NUM_BANKS; i++) begin
|
for (integer i = 0; i < NUM_BANKS; i++) begin
|
||||||
if (per_bank_core_rsp_valid[i]) begin
|
if (per_bank_core_rsp_valid[i]) begin
|
||||||
core_rsp_tag_unqual = per_bank_core_rsp_tag[i];
|
core_rsp_tag_unqual = per_bank_core_rsp_tag[i];
|
||||||
sel_tag_id = per_bank_core_rsp_tag[i][CORE_TAG_ID_BITS-1:0];
|
|
||||||
break;
|
break;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for (integer i = 0; i < NUM_BANKS; i++) begin
|
for (integer i = 0; i < NUM_BANKS; i++) begin
|
||||||
if (per_bank_core_rsp_valid[i]
|
if (per_bank_core_rsp_valid[i]
|
||||||
&& (per_bank_core_rsp_tag[i][CORE_TAG_ID_BITS-1:0] == sel_tag_id)) begin
|
&& (per_bank_core_rsp_tag[i][CORE_TAG_ID_BITS-1:0] == core_rsp_tag_unqual[CORE_TAG_ID_BITS-1:0])) begin
|
||||||
core_rsp_valid_unaual_any = 1;
|
core_rsp_valid_unaual_any = 1;
|
||||||
core_rsp_valid_unqual[per_bank_core_rsp_tid[i]] = 1;
|
core_rsp_valid_unqual[per_bank_core_rsp_tid[i]] = 1;
|
||||||
core_rsp_data_unqual[per_bank_core_rsp_tid[i]] = per_bank_core_rsp_data[i];
|
core_rsp_data_unqual[per_bank_core_rsp_tid[i]] = per_bank_core_rsp_data[i];
|
||||||
|
|||||||
@@ -60,25 +60,21 @@ module VX_generic_queue #(
|
|||||||
full_r <= 0;
|
full_r <= 0;
|
||||||
used_r <= 0;
|
used_r <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (push) begin
|
assert(!push || !full);
|
||||||
assert(!full);
|
assert(!pop || !empty);
|
||||||
if (!pop) begin
|
if (push && !pop) begin
|
||||||
empty_r <= 0;
|
empty_r <= 0;
|
||||||
if (used_r == ADDRW'(SIZE-1)) begin
|
if (used_r == ADDRW'(SIZE-1)) begin
|
||||||
full_r <= 1;
|
full_r <= 1;
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if (pop) begin
|
if (pop && !push) begin
|
||||||
assert(!empty);
|
full_r <= 0;
|
||||||
if (!push) begin
|
if (used_r == ADDRW'(1)) begin
|
||||||
full_r <= 0;
|
empty_r <= 1;
|
||||||
if (used_r == ADDRW'(1)) begin
|
end;
|
||||||
empty_r <= 1;
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
used_r <= used_r + (ADDRW'(push) - ADDRW'(pop));
|
used_r <= used_r + ADDRW'($signed(2'(push) - 2'(pop)));
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user