Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // the solution
- module PipelinedAdd4;
- input Vector#(4, Word) in;
- RegU#(Vector#(2, Word)) pipeReg1;
- RegU#(Word) pipeReg2;
- method Word out = pipeReg2;
- rule tick;
- Vector#(2, Word) newPipeReg1;
- newPipeReg1[0] = in[0]+in[1];
- newPipeReg2[1] = in[2]+in[3];
- pipeReg1 <= newPipeReg1;
- Word newPipeReg2 = pipeReg1[0] + pipeReg1[1];
- pipeReg2 <= newPipeReg2;
- endrule
- endmodule
- // note, this is different from vector of registers!
- module PipelinedAdd4;
- input Vector#(4, Word) in;
- Vector#(2, RegU#(Word)) pipeReg1;
- RegU#(Word) pipeReg2;
- method Word out = pipeReg2;
- rule tick;
- pipeReg1[0] <= in[0]+in[1];
- pipeReg1[1] <= in[2]+in[3];
- pipeReg2 <= pipeReg1[0] + pipeReg1[1];
- endrule
- endmodule
- // or, we could just not separate the stages
- module PipelinedAdd4;
- input Vector#(4, Word) in;
- Vector#(3, RegU#(Word)) s;
- method Word out = s[2];
- rule tick;
- s[0] <= in[0]+in[1];
- s[1] <= in[2]+in[3];
- s[2] <= s[0]+s[1];
- endrule
- endmodule
- // or make register of vector
- module PipelinedAdd4;
- input Vector#(4, Word) in;
- RegU#(Vector#(3, Word)) s;
- method Word out = s[2];
- rule tick;
- Vector#(3, Word) sp;
- sp[0] = in[0]+in[1];
- sp[1] = in[2]+in[3];
- sp[2] = s[0]+s[1]; // careful, must refer to s in this cycle not sp
- s <= sp;
- endrule
- endmodule
- // ok, let's do by-stage solution with valid bit
- module PipelinedAdd4;
- input Maybe#(Vector#(4, Word)) in default = Invalid;
- RegU#(Maybe#(Vector#(2, Word))) pipeReg1; // Maybe#(RegU#(...)) doesn't make sense.
- RegU#(Maybe#(Word)) pipeReg2; // also, it's better to have Maybe#(Vector#(...)) than Vector#(Maybe#(...))
- method Maybe#(Word) out = pipeReg2;
- rule tick;
- if (isValid(in)) begin
- Vector#(2, Word) newPipeReg1Data;
- Vector#(4, Word) in_v = fromMaybe(?, in);
- newPipeReg1Data[0] = in_v[0] + in_v[1];
- newPipeReg1Data[1] = in_v[1] + in_v[2];
- pipeReg1 <= Valid(newPipeReg1Data);
- end else begin
- pipeReg1 <= Invalid;
- end
- if (isValid(pipeReg1)) begin
- Vector#(2, Word) pipeReg1_v = fromMaybe(?, pipeReg1);
- pipeReg2 <= Valid(pipeReg1_v[0]+pipeReg1_v[1]);
- end else begin
- pipeReg2 <= Invalid;
- end
- endrule
- endmodule
- // alternatively, we can just focus on the data and valid bits separately
- // (not fully, since Minispec requires us to provide data with Valid at the same time.)
- module PipelinedAdd4;
- input Maybe#(Vector#(4, Word)) in default = Invalid;
- RegU#(Maybe#(Vector#(2, Word))) pipeReg1;
- RegU#(Maybe#(Word)) pipeReg2;
- method Maybe#(Word) out = pipeReg2;
- rule tick;
- Vector#(2, Word) newPipeReg1Data;
- Vector#(4, Word) in_v = fromMaybe(?, in);
- newPipeReg1Data[0] = in_v[0] + in_v[1];
- newPipeReg1Data[1] = in_v[1] + in_v[2];
- pipeReg1 <= isValid(in) ? Valid(newPipeReg1Data) : Invalid;
- Vector#(2, Word) pipeReg1_v = fromMaybe(?, pipeReg1);
- pipeReg2 <= isValid(pipeReg1) ? Valid(pipeReg1_v[0]+pipeReg1_v[1]) : Invalid;
- endrule
- endmodule
- // now with stall signal. we should think backward.
- module PipelinedAdd4;
- input Maybe#(Vector#(4, Word)) in default = Invalid;
- input Bool outStall default = False; // NEW INPUT!!
- RegU#(Maybe#(Vector#(2, Word))) pipeReg1;
- RegU#(Maybe#(Word)) pipeReg2;
- method Maybe#(Word) out = pipeReg2;
- rule tick;
- Bool stallpipeReg2 = outStall && isValid(stage[1]);
- // 1. pipeReg2 full, outStall is true -> pipeReg2 data mustn't change.
- // 2. pipeReg2 full, outStall is false -> pipeReg2 presents data, which is consumed,
- // so must take data from stage 0.
- // 3. pipeReg2 empty, outStall is true -> pipeReg2 should take data from pipeReg1.
- // 4. pipeReg2 empty, outStall is false -> pipeReg2 should take data from pipeReg1.
- // what if stallpipeReg2 = outStall; only?
- // 1. pipeReg2 full, outStall is true -> pipeReg2 data mustn't change.
- // 2. pipeReg2 full, outStall is false -> data is taken from stage 0. fine.
- // 3. pipeReg2 empty, outStall is true -> we don't take data. loss of throughput, similar to global stall.
- // 4. pipeReg2 empty, outStall is false -> data is taken from stage 0. fine.
- // what if stallpipeReg2 = isValid(stage[1]); only?
- // 1. pipeReg2 full, outStall is true -> pipeReg2 data mustn't change. fine.
- // 2. pipeReg2 full, outStall is false -> consumer already takes data, but we didn't invalidate this. bad.
- // fix: if full, must invalidate if outStall is false.
- // (careful, don't invalidate if outStall is true!)
- // 3. pipeReg2 empty, outStall is true -> pipeReg2 takes data from stage 0. fine.
- // 4. pipeReg2 empty, outStall is false -> pipeReg2 takes data from stage 0. fine.
- if (!stallpipeReg2) begin
- Vector#(2, Word) pipeReg1_v = fromMaybe(?, pipeReg1);
- pipeReg2 <= isValid(pipeReg1) ? Valid(pipeReg1_v[0]+pipeReg1_v[1]) : Invalid;
- end
- Bool stallpipeReg1 = stallpipeReg2 && isValid(stage[0]);
- if (!stallpipeReg1) begin
- Vector#(2, Word) newPipeReg1Data;
- Vector#(4, Word) in_v = fromMaybe(?, in);
- newPipeReg1Data[0] = in_v[0] + in_v[1];
- newPipeReg1Data[1] = in_v[1] + in_v[2];
- pipeReg1 <= isValid(in) ? Valid(newPipeReg1Data) : Invalid;
- end
- // Bool stallInput = stallpipeReg1 && isValid(in);
- // why && with isValid(in)? so, if producer doesn't have input yet, we encourage
- // the producer to try to provide output as fast as possible.
- // this really shouldn't matter, though, because one implicit rule is that
- // producer should try to produce output on best-effort basis, regardless of the received stall signal.
- // in fact, if valid depends on stall, we have a combinational loop!
- endrule
- // problem: method should not access input, by convention:
- // method Bool isFull = outStall && isValid(pipeReg1) && isValid(pipeReg2);
- // solution: we could do this, but ugly:
- // method Bool isFull(Bool outStall) = outStall && isValid(pipeReg1) && isValid(pipeReg2);
- // or just rely on the producer to have access to consumer's stall signal
- method Bool isFull = isValid(pipeReg1) && isValid(pipeReg2);
- // what happens if the producer doesn't check the consumer's stall signal?
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement