2
\$\begingroup\$

I am using RoCC interface to communicate with Memory in chipyard.

The memory has the width of 64 bits, and I need to read the first 64 bits and put it in lower register and then read the next 64 bits and put in the upper register, then make my own packet of data by packet <= {upper, lower};

And repeat the process until I read all the required values from the memory.

The problem is when I request to LOAD data from memory, sometimes during the memory response valid signal there are two 64 bits and other times there is only one. Please see the picture attached below:

enter image description here

This is my code to get the upper and lower values:

reg [63:0] upper, lower;
reg [127:0] packet;
reg [1:0] counter;

always @(posedge clock) begin
    if (reset) begin
        lower <= 64'd0;
        upper <= 64'd0;
        counter <= 2'd0;
        packet <= 128'd0;
    end else begin
        if (mem_resp_valid) begin
            if (counter == 2'd0) begin
                lower <= mem_resp_data;
                counter <= counter + 2'd1;
            end else begin
                upper <= mem_resp_data;
                counter <= 2'd0;
            end
        end
        packet <= {upper, lower};

    end
end

I use packet in the other part of the design.

The lower values are correct, but I am not getting the right values for the upper after the fourth mem_resp_valid where there is only one data valid instead of two.

The expected values for the lower and upper are as follows:

lower1 = 1
upper1 = 2

lower2 = 3
upper2 = 4

lower3 = 5
upper3 = 6   // but gets the same value of lower3 instead

EDIT the data values stored in memory are organized like:

enter image description here

And this how I make LOAD requests from the Memory:

if(mem_req_ready) begin
    mem_req_valid <= 1'b1;
    mem_req_cmd <= 5'd0;       // zero means LOAD. one means STORE
    mem_req_size <= 2'h3;      // size 3 means, load 2^3 bytes on each request, here i need 64 bits hence 3
    mem_req_tag <= mem_req_tag + 8'h1;

    mem_req_signed <= 1'b1;
    mem_req_mask <= 8'h11;  // this is to set how many of the bytes for store request are valid

    if (mem_req_addr == 40'd0) 
      mem_req_addr  <= src_addr; // start fetching from source address/ initial address
    else begin
      mem_req_addr <= mem_req_addr + 40'h8;       
    end
  end

So I need to put 1, 3, 5, ... in the lower and 2, 4, 6, ... in the upper. But I don't know why for some values, the mem_resp_valid is 2 cycles and for others is one cycle.

\$\endgroup\$
7
  • \$\begingroup\$ I don't understand the problem. During the fourth mem_resp_valid pulse, it is clear that mem_resp_data has the same value for both clock cycles, so why wouldn't you expect that both lower and upper end up with that same value? The *7e data becomes the lower value for the following packet. \$\endgroup\$
    – Dave Tweed
    Oct 29, 2023 at 11:52
  • \$\begingroup\$ @DaveTweed I just updated my post . please let me know if you need more info \$\endgroup\$ Oct 29, 2023 at 16:09
  • \$\begingroup\$ OK, the new timing diagram adds some key information. But you can't keep feeding us tiny tidbits of code. If you want serious help with this, you need to provide an MCVE, as well as explain exactly what the difference is between what you expect to happen and what actually happens. I'm assuming (because you haven't said) that this is an AXI memory interface, or something very similar. In this kind of interface, you're making a new request on every clock cycle for which both mem_req_ready and mem_req_valid are true. \$\endgroup\$
    – Dave Tweed
    Oct 29, 2023 at 16:50
  • \$\begingroup\$ ... On the second time that mem_req_ready goes high, you're providing the same address (...4260) for both clock cycles, and that's why the memory returns the same word (...0005) twice in its response. \$\endgroup\$
    – Dave Tweed
    Oct 29, 2023 at 16:51
  • \$\begingroup\$ Thank you for your feedback. I'll try to share an MCVE. Yes, RoCC is similar to AXI but not the same. This is the interface between the accelerator and L1 cache in Rocket-chip. I am using chipyard environment and made some changes to chisel/scala code to make this to work. So I hope my MCVE will be enough for my problem. \$\endgroup\$ Oct 29, 2023 at 17:19

1 Answer 1

2
\$\begingroup\$

The data value of 6 on mem_resp_data is only held for one cycle, and it is the cycle when count is 0. This means that lower samples the 6 data in that cycle. During that cycle, upper does not sample mem_resp_data, so it retains its previous value 5. The Verilog simulation is behaving as expected.

If you want upper to sample the *6 data in the next cycle (when count is 1), you need to extend the mem_resp_data into the next cycle.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.