Site Logo
Find in
This is TikiWiki 1.9.7 -Sirius- © 2002–2006 by the Tiki community Thu 02 of Sep, 2010 [17:05 UTC]
Login
[ register | I forgot my password ]
Menu [hide]
 Home
 Contact us
 Stats
 Categories
 Calendar
Toggle  Wiki
 Wiki Home
 Last Changes
 Dump
 Rankings
 List pages
 Orphan pages
 Sandbox
 Print
Toggle  Blogs
 List blogs
 Rankings

TutorialPipelines

Coding processing pipelines in Verilog
3D browser print PDF
English

Coding Processing Pipelines in Verilog

By Timothy Miller

This is a tutorial, you might say, on coding processing pipelines in Verilog. The objective is to provide templates that people can fill in with their code, where the underlying pipeline mechanics are designed to be fast and efficient. I'm describing what I call a "packing" pipeline; this means that if something is holding up the pipeline further down, but there are bubbles (stages that have nothing to do), earlier stages will be able to progress until the pipeline is completely full.

We design pipelines in logical sections. A top-level module for a section will have an interface that conforms to the fifo protocol. A section contains multiple stages, however many are logical for the function being computed. However for performance, there may be places where you'd want to break the pipeline more finely.

There are five major kinds of pipeline modules:

1. HEADER stages are designed to break the combinatorial chains associated with busy signals that control pipeline flow. Each stage pays attention to the same busy signal, and together with internal busy signals, fanouts and levels of logic accumulate, and we want to limit that. Think of a header stage as a fifo that holds zero or one entry.

2. DUMMY stages are intended to break combinatorial chains associate with the data flowing through the pipeline. These are practically manditory following a header stage, but they're also very useful in some cases with stages that do I/O with logic outside of the pipeline. These are sometimes referred to as "drive" stages.

3. PROCESS stages simply perform some slice of the function being computed. The developer breaks logic into logical pipeline stages, and each of those corresponds to one of these physical stages.

4. IO stages are also PROCESS stages, but they're ones that do I/O with something external to the pipeline and thus may become "busy." This status must be fed back up the pipeline to hold up other stages.

5. FOOTER stages aren't pipeline stages. They just cap off the pipeline so that the output of the top-level module uses fifo protocol.

Pipeline stages typically have multiple signals as inputs and outputs. However, for the sake of generality, we will treat each stage as having one data word in and one data word out. Each is likely to be a different length.

HEADER stage template


module HEADER_stage(
    input clock,
    input reset_,

    // Input channel
    input [INSIZE] input_data,
    input input_enq,
    output im_busy,

    // Output channel
    output [INSIZE] output_data,
    output output_valid,
    input next_advance
);

// Holding register for when we're busy
reg [INSIZE] hold_data;
reg holding;
assign im_busy = holding;

// Select input or holding data for next stage
assign output_data = holding ? hold_data : input_data;
// Indicate if we're offering data to the next stage
assign output_valid = holding || input_enq;


always @(posedge clock or negedge reset_) begin
    if (!_reset) begin
        holding <= 0;
        hold_data <= 0;
    end else begin
        // If we're not holding, grab data, whether or not we need it
        if (!holding) hold_data <= input_data;

        // Compute whether or not we're going to hold data
        holding <= !next_advance && output_valid;
    end
end

endmodule


DUMMY stage template

module DUMMY_stage(
    input clock,
    input reset_,

    // Input channel
    input [INSIZE] input_data,
    input input_valid,
    output i_advance,

    // Output channel
    output reg [INSIZE] output_data,
    output reg output_valid,
    input next_advance
);

assign i_advance = next_advance;

always @(posedge clock or negedge reset_) begin
    if (!reset_) begin
        output_valid <= 0;
        output_data <= 0;
    end else begin
        // If next stage advances, so can I.
        if (next_advance) begin
            output_valid <= input_valid;
            output_data <= input_data;
        end
    end
end

endmodule


PROCESS stage template

module PROCESS_stage(
    input clock,
    input reset_,

    // Input channel
    input [INSIZE] input_data,
    input input_valid,
    output i_advance,

    // Output channel
    output reg [OUTSIZE] output_data,
    output reg output_valid,
    input next_advance
);

assign i_advance = next_advance;


// Instantiate module that performs computation from input
// to output
wire [OUTSIZE] my_data;
wire my_valid;
my_combinatorial_logic mcl (.input_data(input_data),
    .output_data(my_data), .output_valid(my_valid));


always @(posedge clock or negedge reset_) begin
    if (!reset_) begin
        output_valid <= 0;
        output_data <= 0;
    end else begin
        // If next stage advances, so can I.
        if (next_advance) begin
            output_valid <= my_valid && input_valid;
            output_data <= my_data;
        end
    end
end

endmodule


IO stage template

module IO_stage(
    input clock,
    input reset_,

    // Input channel
    input [INSIZE] input_data,
    input input_valid,
    output i_advance,

    // Output channel
    output reg [OUTSIZE] output_data,
    output reg output_valid,
    input next_advance,

    // External connections
    input [IOINSIZE] io_input_data;
    output [IOOUTSIZE] io_output_data;
    input its_busy,   // other logic is busy
    output im_busy    // I am busy for other logic
);


wire expecting_io;
// I can't do any I/O if I have no expectation of it
assign im_busy = !input_valid || !next_advance || !expecting_io;


// Report to previous stage that I cannot advance if I/O is
// holding me up
wire my_busy = input_valid && expecting_io && its_busy;
assign i_advance = next_advance && !my_busy;


// Instantiate module that performs computation from input
// to output
wire [OUTSIZE] my_data;
wire my_valid;
my_combinatorial_logic mcl (.input_data(input_data),
    .output_data(my_data), .output_valid(my_valid),
    .io_input_data(io_input_data), .io_output_data(io_output_data),
    .expecting(expecting_io),
    .clock(clock), .reset_(reset_));



always @(posedge clock or negedge reset_) begin
    if (!reset_) begin
        output_valid <= 0;
        output_data <= 0;
    end else begin
        // If next stage advances, so can I.
        if (next_advance) begin
            output_valid <= my_valid && input_valid;
            output_data <= my_data;
        end
    end
end

endmodule


FOOTER stage template

module FOOTER_stage(
    // Input channel
    input [INSIZE] input_data,
    input input_valid,
    output i_advance,

    // Output channel
    output reg [INSIZE] output_data,
    output reg output_enq,
    input output_busy
);


assign output_enq = input_valid;
assign output_data = input_data;
assign i_advance = !output_busy || !input_valid;

endmodule

Created by: LourensVeen last modification: Friday 28 of December, 2007 [18:25:54 UTC] by LourensVeen


source
history
similar
RSS Wiki RSS Blogs
Übersetzen Sie diese Seite ins Deutsche
Traduzca esta paginación a español
Traduisez cette page en français
Tradurre questa pagina in italiano
Traduza esta página em portuguêses
翻译这页成汉语 (CN)
日本語にこのページを翻訳しなさい (Nihongo)
한국인으로 이 페이지를 번역하십시요 (Hangul)
[ Execution time: 0.57 secs ]   [ Memory usage: 7.40MB ]   [ 45 database queries used ]   [ GZIP Disabled ]   [ Server load: 0.42 ]
How buy cialis 20mg online
kamagra 100mg How download mp3 music online
sex dating