Latency(CLK) | 1 |
module compress(iVld, iStall, iNew, iData, oVld, oStall, oData, reset, clk);
parameter W = 32;
parameter NOP = 2'h0;
parameter PLUS1 = 2'h1;
parameter PLUS2 = 2'h2;
parameter CHANGE = 2'h3;
input iVld;
output iStall;
input iNew;
input [W-1:0] iData;
output oVld;
input oStall;
output [W-1:0] oData;
input reset;
input clk;
reg [W-1:0] lData; // Latched Data
wire [W-1:0] lData0; // Latched Data + 0
wire [W-1:0] lData1; // Latched Data + 1
wire [W-1:0] lData2; // Latched Data + 2
wire eq0;
wire eq1;
wire eq2;
wire iOpVld;
wire iOpStall;
reg [1:0] iOpData; // Operation Code
wire iItVld;
wire iItStall;
reg [W-1:0] iItData; // Initial Data
wire oOpVld;
wire oOpStall;
wire [1:0] oOpData; // Operation Code
wire oItVld;
wire oItStall;
wire [W-1:0] oItData; // Initial Data
reg [W-1:0] oData;
wire iAlloc = iVld & !iStall;
wire oAlloc = oVld & !oStall;
wire oNew = (oOpData == CHANGE);
reg [W-1:0] acc;
// Past Data for Comparison
always @(posedge clk)
if (iAlloc)
lData <= #1 iData;
assign iStall = iOpStall | iItStall;
assign lData0 = lData;
assign lData1 = lData + 'd1;
assign lData2 = lData + 'd2;
assign eq0 = (iData == lData0);
assign eq1 = (iData == lData1);
assign eq2 = (iData == lData2);
assign iOpVld = iVld & !iItStall;
assign iItVld = iVld & !iOpStall;
// Operation Code
always @(iNew or eq0 or eq1 or eq2)
casex ({iNew, eq2, eq1, eq0})
4'b1xxx,
4'b0000: iOpData = CHANGE;
4'b0001: iOpData = NOP;
4'b001x: iOpData = PLUS1;
4'b01xx: iOpData = PLUS2;
endcase
assign iItData = iData;
// Operation FIFO (Depth 2^4, Data Width W bit)
fifo #(2, 4) opFifo (
.iVld (iOpVld),
.iStall (iOpStall),
.iData (iOpData),
.oVld (oOpVld),
.oStall (oOpStall),
.oData (oOpData),
.reset (reset),
.clk (clk)
);
// Initial FIFO (Depth 2^1, Data Width W bit)
fifo #(W, 1) itFifo (
.iVld (iItVld),
.iStall (iItStall),
.iData (iItData),
.oVld (oItVld),
.oStall (oItStall),
.oData (oItData),
.reset (reset),
.clk (clk)
);
// Accumulator
always @(posedge clk)
if (oAlloc)
acc <= #1 oData;
// Operation
always @(oOpData or oItData or acc)
casex (oOpData)
NOP: oData = acc;
PLUS1: oData = acc + 'd1;
PLUS2: oData = acc + 'd2;
CHANGE: oData = oItData;
endcase
assign oOpStall = oStall | !oItVld;
assign oItStall = oStall | !oOpVld & !oNew;
assign oVld = oOpVld & (!oItStall | !oNew);
endmodule
|