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)