2

I implemented the single-cycle MIPS design from "Computer Organisation and Design" in Verilog, shown below:

enter image description here

I used my own "ideal" data memory implementation, which asynchronously presents the read data on the output, and writes data on the rising edge of the clock. This neatly works with the rest of my design:

module data_memory(
    input clk,
    input [15:0] address,
    input cs_mem_read,
    input cs_mem_write,
    input [15:0] data_in,
    output [15:0] data_out
);

reg [15:0] memory [63:0];

always @(posedge clk) begin
    if(cs_mem_write)
        memory[internal_address] <= data_in;
end

assign data_out = (cs_mem_read == 1'b1) ? memory[internal_address] : 16'd0;

Now, I want to use the "Embedded Block RAM" modules my FPGA (ice40 HX8K) supports. In the documentation, they are described as both writing on either falling or rising clock edge (which is fine), but they also read synchronously, which I don't know how to make compatible with my design!

enter image description here

The problem is that at the write back stage, which happens with the rising clock edge, the results from the RAM read are required to already be stable, which is just not the case if I only just started reading from the RAM with the rising edge. But I also want this to stay a single-cycle design.

How can I approach this? My idea was to use the falling edge of the clock to perform the read, but I read online that this approach would introduce another clock domain which is regarded as a thing beginners shouldn't do. Additionally, this would fail if the first instruction is a memory read instruction, since no falling edge happens before the first rising edge. How can this be solved?

0 Answers0