blob: 388a50a9a652323ea33d5c8a80c718df449db423 [file] [log] [blame]
//
// description:
// 1. control to pop data from Command Queue and push data into Uop Queue.
//
// features:
// 1. decode_ctrl will push data to Uops Queue only when Uops Queue has 4 free spaces at least.
`include "rvv_backend.svh"
module rvv_backend_decode_ctrl
(
clk,
rst_n,
pkg_valid,
uop_valid_de2uq,
uop_de2uq,
uop_index_remain,
pop,
push,
dataout,
fifo_full_uq2de,
fifo_almost_full_uq2de
);
//
// interface signals
//
// global signals
input logic clk;
input logic rst_n;
// decoded uops
input logic [`NUM_DE_INST-1:0] pkg_valid;
input logic [`NUM_DE_INST-1:0][`NUM_DE_UOP-1:0] uop_valid_de2uq;
input UOP_QUEUE_t [`NUM_DE_INST-1:0][`NUM_DE_UOP-1:0] uop_de2uq;
// uop_index for decode_unit
output logic [`UOP_INDEX_WIDTH-1:0] uop_index_remain;
// pop signals for command queue
output logic [`NUM_DE_INST-1:0] pop;
// signals from Uops Quue
output logic [`NUM_DE_UOP-1:0] push;
output UOP_QUEUE_t [`NUM_DE_UOP-1:0] dataout;
input logic fifo_full_uq2de;
input logic [`NUM_DE_UOP-1:1] fifo_almost_full_uq2de;
//
// internal signals
//
// get last uop signal
logic [`NUM_DE_INST-1:0] last_uop_unit;
logic [`NUM_DE_UOP-1:0] get_unit1_last_signal;
// the quantity of valid 1 in uop_valid[0]
logic [`NUM_DE_UOP_WIDTH-1:0] quantity;
// fifo is ready when it has 4 free spaces at least
logic fifo_ready;
// signals in uop_index DFF
logic uop_index_clear;
logic uop_index_enable_unit0;
logic uop_index_enable_unit1;
logic uop_index_enable;
logic [`UOP_INDEX_WIDTH-1:0] uop_index_din;
// used in getting push0-3
logic [`NUM_DE_UOP-1:0] push_valid;
// for-loop
genvar i;
//
// ctroller
//
// get the quantity of valid 1 in uop_valid[0]
always_comb begin
// initial
quantity = 'b0;
case(uop_valid_de2uq[0][`NUM_DE_UOP-1:0])
4'b0001:
quantity = 'd1;
4'b0011:
quantity = 'd2;
4'b0111:
quantity = 'd3;
4'b1111:
quantity = 'd4;
endcase
end
// get unit0 last uop signal
mux8_1
#(
.WIDTH (1)
)
mux_unit0_last
(
.sel (quantity),
.indata0 (1'b0),
.indata1 (1'b1),
.indata2 (1'b1),
.indata3 (1'b1),
.indata4 (uop_de2uq[0][`NUM_DE_UOP-1].last_uop_valid),
.indata5 (1'b0),
.indata6 (1'b0),
.indata7 (1'b0),
.outdata (last_uop_unit[0])
);
// get unit1 last uop signal
assign get_unit1_last_signal[3] = uop_de2uq[1][0].last_uop_valid;
assign get_unit1_last_signal[2] = uop_de2uq[1][1].last_uop_valid || get_unit1_last_signal[3];
assign get_unit1_last_signal[1] = uop_de2uq[1][2].last_uop_valid || get_unit1_last_signal[2];
assign get_unit1_last_signal[0] = uop_de2uq[1][3].last_uop_valid || get_unit1_last_signal[1];
mux8_1
#(
.WIDTH (1)
)
mux_unit1_last
(
.sel (quantity),
.indata0 (get_unit1_last_signal[0]),
.indata1 (get_unit1_last_signal[1]),
.indata2 (get_unit1_last_signal[2]),
.indata3 (get_unit1_last_signal[3]),
.indata4 (1'b0),
.indata5 (1'b0),
.indata6 (1'b0),
.indata7 (1'b0),
.outdata (last_uop_unit[1])
);
// get fifo_ready
assign fifo_ready = !(fifo_full_uq2de | (|fifo_almost_full_uq2de));
// get pop signal to Command Queue
assign pop[0] = pkg_valid[0]&((last_uop_unit[0]&fifo_ready) || (uop_valid_de2uq[0][`NUM_DE_UOP-1:0]=='b0));
assign pop[1] = pop[0]&pkg_valid[1]&((last_uop_unit[1]&fifo_ready) || (uop_valid_de2uq[1][`NUM_DE_UOP-1:0]=='b0));
// instantiate cdffr for uop_index
// clear signal
assign uop_index_clear = (pop[0]&(!pkg_valid[1])) | pop[1];
// enable signal
assign uop_index_enable_unit0 = pkg_valid[0]&(uop_valid_de2uq[0][`NUM_DE_UOP-1:0]!='b0)&(last_uop_unit[0]=='b0)&fifo_ready;
assign uop_index_enable_unit1 = pkg_valid[1]&(uop_valid_de2uq[1][`NUM_DE_UOP-1:0]!='b0)&(last_uop_unit[1]=='b0)&fifo_ready&pop[0];
assign uop_index_enable = uop_index_enable_unit0 | uop_index_enable_unit1;
// datain signal
always_comb begin
// initial
uop_index_din = uop_index_remain;
case(1'b1)
uop_index_enable_unit0:
uop_index_din = uop_de2uq[0][`NUM_DE_UOP-1].uop_index + 1'b1;
uop_index_enable_unit1: begin
case(quantity)
'd0:
uop_index_din = uop_de2uq[1][3].uop_index + 1'b1;
'd1:
uop_index_din = uop_de2uq[1][2].uop_index + 1'b1;
'd2:
uop_index_din = uop_de2uq[1][1].uop_index + 1'b1;
'd3:
uop_index_din = uop_de2uq[1][0].uop_index + 1'b1;
'd4:
uop_index_din = uop_de2uq[1][0].uop_index;
endcase
end
endcase
end
cdffr
#(
.WIDTH (`UOP_INDEX_WIDTH)
)
uop_index_cdffr
(
.clk (clk),
.rst_n (rst_n),
.c (uop_index_clear),
.e (uop_index_enable),
.d (uop_index_din),
.q (uop_index_remain)
);
// push signal for Uops Queue
mux8_1
#(
.WIDTH (1)
)
mux_push_valid0
(
.sel (quantity),
.indata0 (uop_valid_de2uq[1][0]),
.indata1 (uop_valid_de2uq[0][0]),
.indata2 (uop_valid_de2uq[0][0]),
.indata3 (uop_valid_de2uq[0][0]),
.indata4 (uop_valid_de2uq[0][0]),
.indata5 (1'b0),
.indata6 (1'b0),
.indata7 (1'b0),
.outdata (push_valid[0])
);
mux8_1
#(
.WIDTH (1)
)
mux_push_valid1
(
.sel (quantity),
.indata0 (uop_valid_de2uq[1][1]),
.indata1 (uop_valid_de2uq[1][0]),
.indata2 (uop_valid_de2uq[0][1]),
.indata3 (uop_valid_de2uq[0][1]),
.indata4 (uop_valid_de2uq[0][1]),
.indata5 (1'b0),
.indata6 (1'b0),
.indata7 (1'b0),
.outdata (push_valid[1])
);
mux8_1
#(
.WIDTH (1)
)
mux_push_valid2
(
.sel (quantity),
.indata0 (uop_valid_de2uq[1][2]),
.indata1 (uop_valid_de2uq[1][1]),
.indata2 (uop_valid_de2uq[1][0]),
.indata3 (uop_valid_de2uq[0][2]),
.indata4 (uop_valid_de2uq[0][2]),
.indata5 (1'b0),
.indata6 (1'b0),
.indata7 (1'b0),
.outdata (push_valid[2])
);
mux8_1
#(
.WIDTH (1)
)
mux_push_valid3
(
.sel (quantity),
.indata0 (uop_valid_de2uq[1][3]),
.indata1 (uop_valid_de2uq[1][2]),
.indata2 (uop_valid_de2uq[1][1]),
.indata3 (uop_valid_de2uq[1][0]),
.indata4 (uop_valid_de2uq[0][3]),
.indata5 (1'b0),
.indata6 (1'b0),
.indata7 (1'b0),
.outdata (push_valid[3])
);
generate
for (i=0;i<`NUM_DE_UOP;i++) begin: GET_PUSH
assign push[i] = push_valid[i]&fifo_ready;
end
endgenerate
// data signal for Uops Queue
mux8_1
#(
.WIDTH (`UQ_WIDTH)
)
mux_data0
(
.sel (quantity),
.indata0 (uop_de2uq[1][0]),
.indata1 (uop_de2uq[0][0]),
.indata2 (uop_de2uq[0][0]),
.indata3 (uop_de2uq[0][0]),
.indata4 (uop_de2uq[0][0]),
.indata5 ('0),
.indata6 ('0),
.indata7 ('0),
.outdata (dataout[0])
);
mux8_1
#(
.WIDTH (`UQ_WIDTH)
)
mux_data1
(
.sel (quantity),
.indata0 (uop_de2uq[1][1]),
.indata1 (uop_de2uq[1][0]),
.indata2 (uop_de2uq[0][1]),
.indata3 (uop_de2uq[0][1]),
.indata4 (uop_de2uq[0][1]),
.indata5 ('0),
.indata6 ('0),
.indata7 ('0),
.outdata (dataout[1])
);
mux8_1
#(
.WIDTH (`UQ_WIDTH)
)
mux_data2
(
.sel (quantity),
.indata0 (uop_de2uq[1][2]),
.indata1 (uop_de2uq[1][1]),
.indata2 (uop_de2uq[1][0]),
.indata3 (uop_de2uq[0][2]),
.indata4 (uop_de2uq[0][2]),
.indata5 ('0),
.indata6 ('0),
.indata7 ('0),
.outdata (dataout[2])
);
mux8_1
#(
.WIDTH (`UQ_WIDTH)
)
mux_data3
(
.sel (quantity),
.indata0 (uop_de2uq[1][3]),
.indata1 (uop_de2uq[1][2]),
.indata2 (uop_de2uq[1][1]),
.indata3 (uop_de2uq[1][0]),
.indata4 (uop_de2uq[0][3]),
.indata5 ('0),
.indata6 ('0),
.indata7 ('0),
.outdata (dataout[3])
);
endmodule