[libre-riscv-dev] buffered pipeline
Jacob Lifshay
programmerjake at gmail.com
Tue Mar 12 15:11:28 GMT 2019
the strategy I'm planning on using for the simple barrel processor is just
to have the pipeline never stop, if we encounter a reason an instruction
can't proceed in the current cycle, it is shunted into a delay pipeline to
be retried the next time around.
For stallable pipelines, I think we should name the pipeline control
signals pred_sending, succ_sending, pred_accepting and succ_accepting.
pred_sending is 1 when the input from the predecessor stage will have valid
data at the next clock edge, including when pred_accepting is 0. It is
connected to the current stage from the predecessor stage.
succ_sending is 1 when the output to the successor stage will have valid
data at the next clock edge, including when succ_accepting is 0. It is
connected from the current stage to the successor stage.
pred_accepting is 1 when the current stage can accept data from the
predecessor stage at the next clock edge, including when pred_sending is 0.
It is connected from the current stage to the predecessor stage.
succ_accepting is 1 when the successor stage can accept data from the
current stage at the next clock edge, including when succ_sending is 0. It
is connected from the successor stage to the current stage.
A simple example stage:
module stage(clk, rst, pred_sending, pred_accepting, pred_data,
succ_sending, succ_accepting, succ_data);
input clk;
input rst;
input pred_sending;
output pred_accepting;
input [63:0] pred_data;
output succ_sending;
input succ_accepting;
output [63:0] succ_data;
reg data_valid;
reg [63:0] data;
wire next_data_valid;
assign succ_sending = data_valid;
assign pred_accepting = ~data_valid | succ_accepting;
assign next_data_valid = pred_sending | (~succ_accepting & data_valid);
assign succ_data = data + 1; // stage operation
initial data_valid = 0;
initial data = 0;
always @(posedge clk or posedge rst) begin
if(rst) begin
data_valid <= 0;
data <= 0;
end
else begin
data_valid <= next_data_valid;
data <= pred_data;
end
end
endmodule
Jacob
On Tue, Mar 12, 2019, 06:33 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
wrote:
> https://zipcpu.com/blog/2017/08/14/strategies-for-pipelining.html
>
> i experimentally-implemented the above buffered pipeline, here:
>
> https://git.libre-riscv.org/?p=ieee754fpu.git;a=blob;f=src/add/example_buf_pipe.py;h=b72e1c43904451ba0ef7f9fa78d5417da8de0a8d;hb=0e70fec7c3df1ee97020aa5be6f358c85898a5fb
>
> it is... very confusing. the names stb/busy, there are pairs: input
> and output, however the connection for previous and next is crossed.
>
> in the john dawson code, the stb / ack signals act effectively as a
> clock. you *must* raise and then lower the "ack" signal each and
> every time that data is ready, and the sender will *not* initiate a
> new data send until it has seen that raise *and* lower.
>
> this means that the john dawson code's data receive and transmit rate
> is *half* that of the clock.
>
> by contrast, dan gisselquist's code is designed to keep on receiving
> (or transmitting) data on every clock, for as long as stb is true and
> busy is false. it also seems to cope with all the situations such as
> when input is ready and output is not (this activates "store incoming
> data in buffer") and allows the stage to tell the input to stop
> sending any more data (without losing the *current* data).
>
> there may however be a bug in what dan has published:
> if (!o_stb)
> o_data <= i_data;
>
> i believe this should be "r_data <= i_data" according to the comments,
> given that it says "store incoming data in temporary".
>
> insights and comments appreciated.
>
> l.
>
> _______________________________________________
> libre-riscv-dev mailing list
> libre-riscv-dev at lists.libre-riscv.org
> http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev
>
More information about the libre-riscv-dev
mailing list