Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module sram_controller(
- input memoryClock,
- input `SRAM_ADDR_VEC inAddr,
- inout `SRAM_WORD_VEC data,
- input exec,
- input rw, // r = 0, w = 1
- output busy,
- output ready,
- // physical interface
- output `SRAM_ADDR_VEC physAddr,
- inout `SRAM_WORD_VEC memData,
- output oe,
- output we,
- output ce
- );
- reg `SRAM_ADDR_VEC inAddrBuf;
- reg `SRAM_WORD_VEC dataBuf;
- reg rwBuf;
- reg working = 0;
- reg driveData = 0;
- reg dataReady = 0;
- reg outEnable = 0, writeEnable = 0, chipEnable = 0; // todo init from datasheet
- always @(memoryClock) begin
- if (!memoryClock) begin // falling edge
- if (working) begin
- dataReady <= 0; // un-assert the old data in either case
- if (working && rwBuf) begin // waiting to write
- driveData <= 1; // so drive data for write
- end
- end
- end
- else begin // rising edge
- driveData <= 0; // in any case, we don't need to drive the data to phy anymore
- if (working && !rwBuf) begin // we were waiting for read
- dataBuf <= memData; // latch the read
- dataReady <= 1;
- end
- working <= exec; // if we've got an exec request this tick, we're still working
- if (!exec) begin // go idle
- chipEnable <= 0;
- outEnable <= 0;
- writeEnable <= 0;
- end
- else begin // we've got something to exec
- // update local buffers
- rwBuf <= rw; // capture if this is a read or write cycle
- inAddrBuf <= inAddr; // drive the address
- if (rw) dataBuf <= data;
- // read cycle 2, write cycle 3 from the datasheet
- // both have zero required skew between O/WE and CE.
- // we wait to drive the output data in the w cycle
- // until the falling edge of the memory clock
- chipEnable <= 1; // enable chip
- outEnable <= !rw; // rw is low read, high write
- writeEnable <= rw;
- end
- end
- end
- assign busy = exec;
- assign ready = dataReady && !rwBuf;
- assign data = (dataReady) ? dataBuf : 8'bZ;
- assign physAddr = inAddrBuf;
- assign memData = (driveData) ? dataBuf : 8'bZ;
- assign oe = !outEnable;
- assign we = !writeEnable;
- assign ce = !chipEnable;
- endmodule
- // ==============================================================
- module sram_controller(
- input memoryClock,
- input `SRAM_ADDR_VEC inAddr,
- inout `SRAM_WORD_VEC data,
- input exec,
- input rw, // r = 0, w = 1
- output busy,
- output ready,
- // physical interface
- output `SRAM_ADDR_VEC physAddr,
- inout `SRAM_WORD_VEC memData,
- output oe,
- output we,
- output ce
- );
- reg `SRAM_ADDR_VEC inAddrR;
- reg `SRAM_WORD_VEC dataR;
- reg execR;
- reg rwR; // r = 0, w = 1
- assign inAddrR = inAddr;
- assign dataR = data;
- assign execR = exec;
- assign rwR = rw;
- reg `SRAM_ADDR_VEC inAddrBuf;
- reg `SRAM_WORD_VEC dataBuf;
- reg rwBuf;
- reg working = 0;
- reg driveData = 0;
- reg dataReady = 0;
- reg outEnable = 0, writeEnable = 0, chipEnable = 0; // todo init from datasheet
- always @(memoryClock) begin
- if (!memoryClock) begin // falling edge
- if (working) begin
- dataReady <= 0; // un-assert the old data in either case
- if (working && rwBuf) begin // waiting to write
- driveData <= 1; // so drive data for write
- end
- end
- end
- else begin // rising edge
- driveData <= 0; // in any case, we don't need to drive the data to phy anymore
- if (working && !rwBuf) begin // we were waiting for read
- dataBuf <= memData; // latch the read (which the compiler says is a bad thing)
- dataReady <= 1;
- end
- else
- dataBuf <= 16'b0;
- dataReady <= 0;
- end
- working <= exec; // if we've got an exec request this tick, we're still working
- if (!execR) begin // go idle
- chipEnable <= 0;
- outEnable <= 0;
- writeEnable <= 0;
- end
- else begin // we've got something to exec
- // update local buffers
- rwBuf <= rwR; // capture if this is a read or write cycle
- inAddrBuf <= inAddrR; // drive the address
- if (rw) dataBuf <= data;
- // read cycle 2, write cycle 3 from the datasheet
- // both have zero required skew between O/WE and CE.
- // we wait to drive the output data in the w cycle
- // until the falling edge of the memory clock
- chipEnable <= 1; // enable chip
- outEnable <= !rw; // rw is low read, high write
- writeEnable <= rw;
- end
- end
- assign busy = exec;
- assign ready = dataReady && !rwBuf;
- assign data = (dataReady) ? dataBuf : 8'bZ;
- assign physAddr = inAddrBuf;
- assign memData = (driveData) ? dataBuf : 8'bZ;
- assign oe = !outEnable;
- assign we = !writeEnable;
- assign ce = !chipEnable;
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement