Here's a new XP10 bridge design.  This one expects fifos to be
attached to it, one for commands (address, write data, read count),
and the other for returning read data.  This doesn't account for HQ,
but logically, HQ goes between this and the physical bridge.  We'll
have to work that out.

/*

Notes:  Due to I/O register latencies, the bridge does not use fifo
protocol.  Busy being asserted means that the Spartan's bridge will
_become_ busy should we keep enqueueing for N more cycles.
As such, bridge commands are still accepted while the bridge busy
is asserted, and it is our responsibility to stop before it's too
late.  The simplest solution is to use a fifo that has a free-entries
output and report busy when free becomes less than a threshold.


All addresses are for 32-bit words.  Byte addresses should have already
been right-shifted.

One useful thing this allows is for, say, HQ to request a read block,
followed by a few writes (that get serviced later), before it pays
attention to the read data.  That doesn't buy us much, though.

To keep things simple, when reads are pending, the bridge is locked.
In theory, HQ could manage things out of order, so we might like to
allow writes to occur during the period between a read request and
when the data starts coming in.  If this becomes a problem, we can
make it smarter later.

*/

module xp10_bridge(
    input clock,   // HQ/bridge clock
    input reset_,

    // Read end of command fifo
    input [1:0] command_in,
    input [31:0] data_in,
    input [3:0] flags_in,
    input valid_in,
    output deq_in,

    // Write end of read data return fifo
    // We ignore 'full'
    output reg [31:0] data_out,
    output reg [3:0] reader_tag,
    output reg enq_out,


    // External interface
    input [31:0] bridge_ad_in,
    output reg [31:0] bridge_ad_out,  // connect in and out signals to same pins
    output reg bridge_oe,      // output enable on bridge_ad
    output reg [3:0] bridge_flags,
    output reg [1:0] bridge_cmd,
    input bridge_rdata_valid,
    input bridge_busy
);



// Commands -- move to header file!
parameter b_idle = 0;
parameter b_addr = 1;
parameter b_rcound = 2;
parameter b_write = 3;



// Busy signals
reg s3busy;
always @(posedge clock) s3busy <= bridge_busy;
reg busy_reading;
reg [6:0] read_counter;
assign deq_in = !busy_reading && !s3busy;




// Accept bridge reads
reg [31:0] bridge_ad_in_d;
reg bridge_rdata_valid_d;
always @(posedge clock) begin
    bridge_ad_in_d <= bridge_ad_in;
    bridge_rdata_valid_d <= bridge_rdata_valid;
end
always @(posedge clock) begin
    data_out <= bridge_ad_in_d;
    enq_out <= bridge_rdata_valid_d && busy_reading;
end



always @(posedge clock or negedge reset_) begin
    if (!reset_) begin
        busy_reading <= 0;
        bridge_oe <= 0;
        bridge_ad_out <= 0;
        bridge_cmd <= 0;
        bridge_flags <= 0;
    end else begin
        bridge_oe <= !busy_reading;  // first cycle after rcount
        // Address, read count, or write data
        bridge_ad_out <= data_in;
        bridge_cmd <= command_in & {2{deq_in && valid_in}}
        // Write bytes or access target
        bridge_flags <= flags_in;

        if (deq_in && valid_in && command_in == b_rcount) begin
            read_count <= data_in;
            busy_reading <= 1;

            // If multiple readers can queue requests, use this
            // to figure out who should accept the data.
            // Otherwise, we'll remove this.
            reader_tag <= flags_in;
        end
        if (bridge_rdata_valid_d && busy_reading) begin
            read_count <= read_count - 1;
            if (read_count <= 1) busy_reading <= 0;
        end
    end
end


endmodule
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)

Reply via email to