At this time, I have only a couple of comments.  I prefix my comments with "--".


module spi_controller(
  clock,
  reset_,      // async negative reset

  // Read/write interface
  busy,        // Is the machine busy working on a read request?
  addr,        // Read or write address of 32-bit word
  write_data,  // Data to be written
  write_bytes, // Byte enables of write data
  read_data,   // Data to be read
  read_out_valid, // Does data in holding buffer correspond with read addr?
  do_read,     // Start a read
  do_write,    // Start a write

  // SPI interface
  SI,
  SO,
  CE_,
  SCK,

  // config
  read_cmd,    // 8-bit command code for read
  read_dummy_byte, // Do I throw away 8 bits when reading?
  write_cmd    // 8-bit command code to write byte
);

input clock, reset_;
output busy;
input [23:2] addr;
input [31:0] write_data;
input [3:0] write_bytes;
output [31:0] read_data;
output read_out_valid;
input do_read, do_write;
input SO;
output SI, CE_, SCK;
input [7:0] read_cmd, write_cmd;
input read_dummy_byte;

reg CE_, SI;
reg SCK;

reg [39:0] ck_out_data;
reg [31:0] ck_in_data;
reg [6:0] bit_counter;
reg enable_read;

reg busy;


-- Don't forget to replace this with a DDR FF

always @(posedge clock) SCK <= 0;
always @(negedge clock) SCK <= !CE_;

wire [1:0] low_addr;
assign low_addr[1] = !(write_bytes[3] || write_bytes[2]);
assign low_addr[0] = !(write_bytes[3] || write_bytes[1]);

assign read_data = ck_in_data;

always @(negedge clock) begin
   if (enable_read)
        ck_in_data <= {ck_in_data[30:0], SO};
end


-- Don't forget to assign read_out_valid


always @(posedge clock or negedge reset_) begin
//    $display("cyc%d %x %x", bit_counter, ck_out_data, ck_in_data);
   if (reset_ == 0) begin
        CE_ <= 1;
        enable_read <= 0;
        bit_counter <= 0;
   end else begin
        if (bit_counter == 0) begin
            if (do_write) begin
                {SI, ck_out_data}
                    <= {write_cmd, addr, low_addr, write_data[7:0], 1'b0};

-- Don't forget to use Howard's code to grab the right byte.

                bit_counter <= 40;
                CE_ <= 0;

-- This may work, but the diagrams show CE going low a cycle earlier.
What you may want to do is set CE_ low here, then on the next cycle is
when the first valid data comes out.  Align clock appropriately.

                busy <= 1;
            end
            else if (do_read) begin
                {SI, ck_out_data} <= {read_cmd, addr, 11'b0};
                bit_counter <= 63;  // It might be 32+31
                CE_ <= 0;  // right time or one cycle later??
                enable_read <= 1;
                busy <= 1;
            end else begin
                CE_ <= 1;
                enable_read <= 0;
                busy <= 0;

-- Often what I do is have busy go low one cycle early.  The idea is
that the counter (whatever it is you're using to control your loop)
never reaches zero if there are back-to-back requests.  There are
other ways to achieve the same effect, and it may not be necessary
here.  In fact, I'm wondering if we really need a busy signal.  When a
read request signal arrives, and it's a miss, we go off and fetch.
Otherwise, we do nothing.  The complication arises in that we (a) set
the address on a miss, but (b) don't want to say the data is valid
until it's all arrived.  I guess we need an internal busy signal that
goes away when the last data bit is stored, allowing read_valid to be
asserted.  If the busy signal goes away one cycle early, and there is
a pipeline delay for read_valid, then it'll go high at the earliest
possible valid time.

            end
      end else begin
            {SI, ck_out_data} <= {ck_out_data, 1'b0};
            bit_counter <= bit_counter - 1;
            busy <= 1;

-- Not that it matters, but there's no need to keep setting busy to
the same value it's already at.  If it's set to a value on every
cycle, then there's more logic on the D input to the flipflop.  If
it's not, then there's less logic on D and then some logic is attached
to the write-enable for the FF.  The result is potentially fewer
levels of logic.  But that doesn't matter here since we're not
performance critical.

      end
  end
end
endmodule


-- We might want to alter the design to read, say, 64 bits at once.
If reads are sequential, it'll be a slight performance boost.  If
reads are random, it'll be a significant penalty.  Actually, we
generally want to avoid reading PROMs anyhow, so maybe this
optimization is not helpful.
_______________________________________________
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