Latency(CLK) | 0 |
module combine(iVld, iStall, iEnd, oVld, oStall, reset, clk);
parameter N = 4;
parameter IDLE = 2'h0,
PASS = 2'h2, // Late End
BLOCK = 2'h3; // Early End
input [N-1:0] iVld;
output [N-1:0] iStall;
input [N-1:0] iEnd;
output oVld;
input oStall;
input reset;
input clk;
reg [N-1:0] cnd[0:N-1]; // Pipeline Condition
reg [N-1:0] cndD[0:N-1]; // Number0 is useless
reg [N-1:0] iDummyVld; // Condition = EARLY
reg [N-1:0] iDummyStall; // Condition = LATE
reg [N-1:0] iDummyVldD;
reg [N-1:0] iDummyStallD;
wire [N-1:0] iAlloc = iVld & ~iStall & iEnd;
wire iDone = &(iAlloc | iDummyStall);
wire nasc = &(iVld | iDummyVld) & ~|oStall;
integer i;
always @(posedge clk)
if (reset) for (i=0; i<N; i=i+1)
cnd[i] <= #1 IDLE;
else for (i=0; i<N; i=i+1)
cnd[i] <= #1 cndD[i];
always @(
cnd[0] or cnd[1] or cnd[2] or cnd[3] or
iAlloc or iDone
) begin
for (i=0; i<N; i=i+1)
cndD[i] = cnd[i]; // Default Case
for (i=0; i<N; i=i+1) case (cnd[i])
IDLE: casex ({iDone, iAlloc[i], iAlloc[0]})
3'b001: cndD[i] = PASS;
3'b01x: cndD[i] = BLOCK;
endcase
PASS: casex ({iDone, iAlloc[i]})
2'b1x: cndD[i] = IDLE;
2'b01: cndD[i] = BLOCK;
endcase
BLOCK: if (iDone)
cndD[i] = IDLE;
endcase
end
always @(
cndD[0] or cndD[1] or cndD[2] or cndD[3]
)
for (i=0; i<N; i=i+1) begin
iDummyVldD[i] = (cndD[i] == PASS);
iDummyStallD[i] = (cndD[i] == BLOCK);
end
always @(posedge clk)
if (reset)
iDummyVld <= #1 {N{1'b0}};
else for (i=0; i<N; i=i+1)
iDummyVld <= #1 iDummyVldD;
always @(posedge clk)
if (reset)
iDummyStall <= #1 {N{1'b0}};
else
iDummyStall <= #1 iDummyStallD;
assign iStall = iDummyStall | {N{!nasc}};
assign oVld = nasc;
endmodule
|