blob: aac41f3b98d1dee60bfd43326131a2b7d2252c1d [file] [log] [blame]
// Description:
// 1. the rvv_backend_dispatch_ctrl is responsible for push uop(s) to RS/ROB and pop uop(s) from UOP_Queue.
`ifndef HDL_VERILOG_RVV_DESIGN_RVV_SVH
`include "rvv_backend.svh"
`endif
`ifndef RVV_DISPATCH__SVH
`include "rvv_backend_dispatch.svh"
`endif
module rvv_backend_dispatch_ctrl
(
raw_uop_rob,
raw_uop_uop,
arch_hazard,
uop_ctrl,
uop_valid_uop2dp,
uop_ready_dp2uop,
rs_valid_dp2alu,
rs_ready_alu2dp,
rs_valid_dp2pmtrdt,
rs_ready_pmtrdt2dp,
rs_valid_dp2mul,
rs_ready_mul2dp,
rs_valid_dp2div,
rs_ready_div2dp,
rs_valid_dp2lsu,
rs_ready_lsu2dp,
mapinfo_valid_dp2lsu,
mapinfo_ready_lsu2dp,
uop_valid_dp2rob,
uop_ready_rob2dp
);
// ---port definition-------------------------------------------------
// ctrl input signal
input RAW_UOP_ROB_t [`NUM_DP_UOP-1:0] raw_uop_rob;
input RAW_UOP_UOP_t [`NUM_DP_UOP-1:1] raw_uop_uop;
input ARCH_HAZARD_t arch_hazard;
input UOP_CTRL_t [`NUM_DP_UOP-1:0] uop_ctrl;
// handshake singals
input logic [`NUM_DP_UOP-1:0] uop_valid_uop2dp;
output logic [`NUM_DP_UOP-1:0] uop_ready_dp2uop;
output logic [`NUM_DP_UOP-1:0] rs_valid_dp2alu;
input logic [`NUM_DP_UOP-1:0] rs_ready_alu2dp;
output logic [`NUM_DP_UOP-1:0] rs_valid_dp2pmtrdt;
input logic [`NUM_DP_UOP-1:0] rs_ready_pmtrdt2dp;
output logic [`NUM_DP_UOP-1:0] rs_valid_dp2mul;
input logic [`NUM_DP_UOP-1:0] rs_ready_mul2dp;
output logic [`NUM_DP_UOP-1:0] rs_valid_dp2div;
input logic [`NUM_DP_UOP-1:0] rs_ready_div2dp;
output logic [`NUM_DP_UOP-1:0] rs_valid_dp2lsu;
input logic [`NUM_DP_UOP-1:0] rs_ready_lsu2dp;
output logic [`NUM_DP_UOP-1:0] mapinfo_valid_dp2lsu;
input logic [`NUM_DP_UOP-1:0] mapinfo_ready_lsu2dp;
output logic [`NUM_DP_UOP-1:0] uop_valid_dp2rob;
input logic [`NUM_DP_UOP-1:0] uop_ready_rob2dp;
// ---internal signal definition--------------------------------------
logic [`NUM_DP_UOP-1:0] uop_valid;
logic [`NUM_DP_UOP-1:0] rs_ready;
// ---code start------------------------------------------------------
genvar i;
generate
for (i=0; i<`NUM_DP_UOP; i++) begin : gen_uop_valid
if (i==0)
assign uop_valid[0] = uop_valid_uop2dp[0] &
~raw_uop_rob[0].vs1_wait &
~raw_uop_rob[0].vs2_wait &
~raw_uop_rob[0].vd_wait &
~raw_uop_rob[0].v0_wait ;
else if (i<`NUM_DP_UOP-1)
assign uop_valid[i] = uop_valid[i-1] &
uop_valid_uop2dp[i] &
~raw_uop_rob[i].vs1_wait &
~raw_uop_rob[i].vs2_wait &
~raw_uop_rob[i].vd_wait &
~raw_uop_rob[i].v0_wait &
~raw_uop_uop[i].vs1_wait &
~raw_uop_uop[i].vs2_wait &
~raw_uop_uop[i].vd_wait &
~raw_uop_uop[i].v0_wait ;
else
assign uop_valid[i] = uop_valid[i-1] &
uop_valid_uop2dp[i] &
~raw_uop_rob[i].vs1_wait &
~raw_uop_rob[i].vs2_wait &
~raw_uop_rob[i].vd_wait &
~raw_uop_rob[i].v0_wait &
~raw_uop_uop[i].vs1_wait &
~raw_uop_uop[i].vs2_wait &
~raw_uop_uop[i].vd_wait &
~raw_uop_uop[i].v0_wait &
~arch_hazard.vr_limit ;
end
for (i=0; i<`NUM_DP_UOP; i++) begin : gen_rs_ready
if (i==0)
always_comb begin
case (uop_ctrl[i].uop_exe_unit)
ALU: rs_ready[0] = rs_ready_alu2dp[0];
MUL,
MAC: rs_ready[0] = rs_ready_mul2dp[0];
CMP,
PMT,
RDT: rs_ready[0] = rs_ready_pmtrdt2dp[0];
DIV: rs_ready[0] = rs_ready_div2dp[0];
LSU: rs_ready[0] = rs_ready_lsu2dp[0]&mapinfo_ready_lsu2dp[0];
default: rs_ready[0] = 1'b0;
endcase
end
else
always_comb begin
case (uop_ctrl[i].uop_exe_unit)
ALU: rs_ready[i] = rs_ready[i-1] & rs_ready_alu2dp[i];
MUL,
MAC: rs_ready[i] = rs_ready[i-1] & rs_ready_mul2dp[i];
CMP,
PMT,
RDT: rs_ready[i] = rs_ready[i-1] & rs_ready_pmtrdt2dp[i];
DIV: rs_ready[i] = rs_ready[i-1] & rs_ready_div2dp[i];
LSU: rs_ready[i] = rs_ready[i-1] & rs_ready_lsu2dp[i] & mapinfo_ready_lsu2dp[i];
default: rs_ready[i] = 1'b0;
endcase
end
end
for (i=0; i<`NUM_DP_UOP; i++) begin: gen_ctrl_output
assign uop_ready_dp2uop[i] = uop_valid[i] &
uop_ready_rob2dp[i] &
rs_ready[i] ;
// CMP&RDT instruction update vd in the last uop.
always_comb begin
case (uop_ctrl[i].uop_exe_unit)
CMP,
RDT: uop_valid_dp2rob[i] = uop_ctrl[i].last_uop_valid ? uop_ready_dp2uop[i] : 1'b0;
default: uop_valid_dp2rob[i] = uop_ready_dp2uop[i];
endcase
end
assign rs_valid_dp2alu[i] = uop_ready_dp2uop[i] &
(uop_ctrl[i].uop_exe_unit == ALU);
assign rs_valid_dp2pmtrdt[i] = uop_ready_dp2uop[i] &
((uop_ctrl[i].uop_exe_unit == PMT) || (uop_ctrl[i].uop_exe_unit == RDT) || (uop_ctrl[i].uop_exe_unit == CMP));
assign rs_valid_dp2mul[i] = uop_ready_dp2uop[i] &
(uop_ctrl[i].uop_exe_unit == MUL || uop_ctrl[i].uop_exe_unit == MAC);
assign rs_valid_dp2div[i] = uop_ready_dp2uop[i] &
(uop_ctrl[i].uop_exe_unit == DIV);
assign rs_valid_dp2lsu[i] = uop_ready_dp2uop[i] &
(uop_ctrl[i].uop_exe_unit == LSU);
assign mapinfo_valid_dp2lsu[i] = rs_valid_dp2lsu[i];
end
endgenerate
endmodule