Ok, here's the bridge for the Spartan chip. What's missing? Right
now, what I need is help with organizing this in SVN and then with
filling in the top-level modules, which is an error-prone job that
needs more eyes.
// Spartan side of the bridge
/*
Notes:
Can only handle even numbers of words in read requests.
Optimizations:
eng_addr and mem_addr could be merged into one register,
where the address loses a bit when connecting to the fifo.
Similar for mem_data and eng_wdata.
*/
module s3_bridge(
input clock,
input reset_,
// External interface
input [31:0] bridge_ad_in,
output reg [31:0] bridge_ad_out, // wire in and out to same pins
output reg bridge_oe,
input [3:0] bridge_flags,
input [1:0] bridge_cmd,
output reg bridge_rdata_valid,
output reg bridge_busy,
// Engine interface
output [15:0] eng_addr,
input [31:0] eng_rdata,
output reg [31:0] eng_wdata,
output reg eng_do_write,
// Write end of memory access fifo
output reg [27:0] mem_addr,
output reg [63:0] mem_data,
output reg [7:0] mem_bytes,
output reg mem_do_write,
output reg mem_do_read,
output reg mem_enq,
input mem_full,
input mem_nearly_full, // When the fifo has <=4 entries free
// (I think 4 is enough; otherwise use 8)
// Read end of memory read return fifo
input [63:0] mem_rdata,
input mem_rdata_valid,
output mem_rdata_deq
);
// Commands -- move to header file!
parameter b_idle = 0;
parameter b_addr = 1;
parameter b_rcount = 2;
parameter b_write = 3;
// These target numbers are different from in the XP10
parameter TARGET_ENG=0;
parameter TARGET_MEM=1;
// Busy
always @(posedge clock) begin
bridge_busy <= mem_nearly_full;
end
// Register bridge inputs
reg [31:0] bridge_ad_in_d;
reg [3:0] bridge_flags_d;
reg [1:0] bridge_cmd_d;
always @(posedge clock) begin
bridge_ad_in_d <= bridge_ad_in;
bridge_flags_d <= bridge_flags;
bridge_cmd_d <= bridge_cmd;
end
// Manage address and memory access
reg [31:0] address;
reg [3:0] target;
reg [6:0] rcount;
always @(posedge clock) begin
if (!mem_full) mem_enq <= 0;
eng_do_write <= 0;
case (bridge_cmd_d)
b_addr: begin
address <= bridge_ad_in_d;
target <= bridge_flags_d;
end
b_rcount: rcount <= bridge_ad_in_d;
b_write: begin
mem_addr <= address[28:1]; // shift correct?
// Cheat by not combining adjacent writes
// This should be easy to optimize later
mem_data <= {bridge_ad_in_d, bridge_ad_in_d};
// Important: Lower address goes into lower half of word
mem_bytes[3:0] <= {4{!address[0]}} & bridge_flags_d;
mem_bytes[7:4] <= {4{address[0]}} & bridge_flags_d;
mem_do_write <= 1;
mem_do_read <= 0;
mem_enq <= target[TARGET_MEM];
end
endcase
if (rcount[6:1]) begin
mem_addr <= address[28:1]; // shift?
mem_do_write <= 0;
mem_do_read <= 1;
mem_enq <= target[TARGET_MEM];
address[6:1] <= address[6:1] + 1;
rcount[6:1] <= rcount[6:1] - 1;
end
end
// Mem and engine read return
reg [6:0] return_half;
reg [1:0] eng_read_count;
always @(posedge clock or negedge reset_) begin
if (!reset_) begin
return_half <= 0;
bridge_oe <= 0;
end else begin
if (bridge_cmd_d == b_rcount) begin
return_half <= 0;
end
bridge_oe <= 0;
bridge_rdata_valid <= 0;
if (target[TARGET_MEM] && mem_rdata_valid) begin
bridge_oe <= 1;
bridge_ad_out <= return_half ?
mem_rdata[63:32] : mem_rdata[31:0];
bridge_rdata_valid <= 1;
end
if (eng_read_count == 1) begin
bridge_oe <= 1;
bridge_ad_out <= eng_rdata;
bridge_rdata_valid <= 1;
end
end
end
// Dequeue when we're sending the top half
assign mem_rdata_deq = return_half;
// Engine register access
always @(posedge clock or negedge reset_) begin
eng_do_write <= 0;
case (bridge_cmd_d)
b_rcount: begin
eng_addr <= address;
// Start counter at 3
eng_read_count <= {2{target[TARGET_ENG]}};
end
b_write: begin
eng_addr <= address;
eng_wdata <= bridge_ad_in_d;
eng_do_write <= target[TARGET_ENG];
end
default:
eng_read_count <= 0;
eng_addr <= 0;
end
endcase
if (eng_read_count) begin
eng_read_count <= eng_read_count - 1;
end
end
endmodule
--
Timothy Normand Miller
http://www.cse.ohio-state.edu/~millerti
Open Graphics Project
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)