On 2007-12-06, Timothy Normand Miller wrote:
> Note that all of this is very important. We need to keep track of
> both the microcode's view of this and the module interface. They're
> _slightly_ different, because they come from different perspectives
> about what's going on, even though they resolve to the same functions.
>
> [...]
Let me just focus on the memory for the time being. I haven't done I/O
ports before, so I first of all want to get the approach right.
First, I think the I/O port is best put in a completely separate module
from the HQ, since it's very OGA1 specific.
I attach a sketch without the PCI bits. It will basically be a big
"case" routing data between a HQ input/output word and multiple external
signals dependent on the I/O address. Now, I'm uncertain about timing
issues. The attached sketch registers it's outputs. My though is that
a more combinatorial I/O unit is infeasible given the big "case". Here
is how I imagine the timing and data flow:
* cycle 0
* The operating mode (store/fetch), address, and optional data is
computed by the ALU and registered at the end of the cycle.
* cycle 1
* The request is now available to the HQ memory stage, and is also
decoded by the I/O unit if applicable since that's just a
combinatorial path from the ALU output.
* For port-write, the I/O unit registers the data on the
appropriate external port at the end of the cycle.
* For port-read the I/O unit registers the data from the appropriate
external port at the end of the cycle.
* cycle 2
* For port-read, the HQ memory stage MUXes the data to it's output
port. This is further routed to the register file and to the
appropriate destination for register-forwarding.
Some minor points:
* Is there anything to gain from arranging the code of the I/O unit
differently? E.g. dispatch between {read, write} before address?
* We could let read-only ports and write-only ports overlap
(arbitrarily) in the address space and add an input which decides
whether HQ is reading or writing. (Given an appropriate
rearrangement of the port numbers, this is equivalent in terms of
gate-count of the I/O unit: Just bundle/unbundle the is-reading
signal with the address signals.)
module oga1hq_io(
input clock,
// HQ interface
input hq_select, // Address is within our range.
input [5:0] hq_addr,
input [31:0] hq_wdata,
output reg [31:0] hq_rdata_o,
// Memory read request queue
input [3:0] mem_readreq_free, // Available req entries, used by microcode
output reg [6:0] mem_readreq_count, // Part of the request
output reg [24:0] mem_readreq_addr, // Address of first req
output reg mem_readreq_enq, // Enqueue into request queue
input mem_readreq_full, // read the fifo interface doc!
// Memory read return queue
input [31:0] mem_readreply_data,
input mem_readreply_valid,
input mem_readreply_count, // How many read words in queue
output reg mem_readreply_deq,
// Memory write requests
input mem_write_full,
output reg mem_write_enq,
output reg [24:0] mem_write_addr,
output reg [31:0] mem_write_data,
input [6:0] mem_write_free // number of requests that can be queued
// TODO: PCI...
);
parameter MEM_READREQ_FREE = 0; // in, free slots in command pipe
parameter MEM_READREQ_COUNT = 1; // out, number of words to read
parameter MEM_READREQ_ADDR_TRIG = 2; // out, first addres to read
parameter MEM_READREPLY_DATA = 3; // in, data stream from memory
parameter MEM_READREPLY_AVAIL = 4; // in, number of words in FIFO
parameter MEM_WRITE_ADDR = 5; // out, start address
parameter MEM_WRITE_FREE = 6; // in, free slots in ouput FIFO
parameter MEM_WRITE_DATA = 7; // out, data stream to memory
// If read and write ports does not overlap, we can ban operations with the
// wrong direction.
wire hq_does_read = hq_select;
wire hq_does_write = hq_select;
always @(posedge clock) begin
// Default output to HQ
hq_rdata_o <= 0;
// Default outputs to memory FIFOs
mem_readreq_enq <= 0;
mem_readreply_deq <= 0;
mem_write_enq <= 0;
// Defaults outputs to PCI FIFOs
// TODO: PCI...
case (hq_addr)
// Memory Read
MEM_READREQ_FREE: hq_rdata_o <= mem_readreq_free;
MEM_READREQ_COUNT: mem_readreq_count <= hq_wdata;
MEM_READREQ_ADDR_TRIG: begin
mem_readreq_addr <= hq_wdata;
mem_readreq_enq <= hq_does_write;
end
MEM_READREPLY_DATA: begin
hq_rdata_o <= mem_readreply_data;
mem_readreply_deq <= hq_does_read;
end
MEM_READREPLY_AVAIL: hq_rdata_o <= mem_readreply_count;
// Memory Write
MEM_WRITE_ADDR: mem_write_addr <= hq_wdata;
MEM_WRITE_FREE: hq_rdata_o <= mem_write_free;
MEM_WRITE_DATA: begin
mem_write_data <= hq_wdata;
mem_write_enq <= hq_does_write;
end
// TODO: PCI...
endcase
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)