Hi everyone, I am trying to write a firmware for ...
# caravel
e
Hi everyone, I am trying to write a firmware for the caravel processor. I want it to send some data and some signals, including the clock to the user_area through the logic analyzer. I'm getting the error below when running the simulation:
/foss/tools/riscv-gnu-toolchain-rv32i/217e7f3debe424d61374d31e33a091a630535937/lib/gcc/riscv32-unknown-linux-gnu/11.1.0/../../../../riscv32-unknown-linux-gnu/bin/ld: test_la.elf section
.data' will not fit in region
dff'
`/foss/tools/riscv-gnu-toolchain-rv32i/217e7f3debe424d61374d31e33a091a630535937/lib/gcc/riscv32-unknown-linux-gnu/11.1.0/../../../../riscv32-unknown-linux-gnu/bin/ld: region
dff' overflowed by 1624 bytes
collect2: error: ld returned 1 exit status
It seems that there is not enough memory for my program. I have declared some large arrays (~160 in size) which have the data and other signals values in them, outside the main function, I think the error is due to these large arrays. I have make the error go away for now by changing the type of the arrays from
int
to
unit8_t
(only works if my data values are small). But I think with defining more variables in my program the error will show itself again, considering the 1KB sram. Any suggestions?
int la_clock [164] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
int la_reset [164] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int la_wr_en [164] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0};
int la_dat_i [164] = { 0, 0, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0, 0};
and in the main function:
for(int i= 0; i < 164; i++){
reg_la0_data  = (0x00000000 | la_dat_i[i]) |
(0x00000000 | la_wr_en[i] << 29) |
(0x00000000 | la_reset[i] << 30) |
(0x00000000 | la_clock[i] << 31) ;
}
@Matt Venn why something like: for(i= 0; i < 164; i++){ reg_mprj_slave = (0x00000000 | la_dat_i[i]); } doesn't work?
m
in what way doesn't it work?
e
@Matt Venn When assign to the la register I get the array data on wdata, but assigning to the wb slave register wont write anything.
m
Where is the wishbone address set?
e
Thanks for the hint. I used the default register (reg_mprj_slave), do I need to set an address for that?
@Matt Venn I defined a new register at the 0x30000000 address in the firmware and added the term( wb_addr_i == BASE_ADDR) inside the always block but the results are the same
m
have you checked my example?
e
Yes I have. As you said in the video writing to the wishbone address will write to client. I want to write multiple times to the same address but it seems it doesn't work.
m
I don't see anywhere where you are setting the address to 0x3000_0000
also your checkbits don't look right to me, and although I let the sim run for a while, it didn't ever print out the test had started
e
Oh sorry, I tested locally, could you check now, please? and the checkbits problem got fixed,thanks
@Matt Venn Could you tell me how to zero out the random values assigned to the wdata at around 150 to 600 us in the screenshot (when using the la)?
m
I don't see any use of the LA in the test verilog/dv/sr_wb
also, I'd advise getting the whole trace, not just the mprj. that will give you a lot more visibility on what is going on
image.png
here's the moment where the data is written via wb to your design
I made a PR with my changes
e
Thanks, yes exactly (assigning one time works). but I want to write different values to the same address. I did the following, for example : reg_base_sr = 0xFF; reg_base_sr = 0x1; reg_base_sr = 0x2; reg_base_sr = 0x3; and the value of 0xFF was the first and the last value written to the design. Why 0x1, 0x2, 0x3 were not written?
@Matt Venn: "I don't see any use of the LA in the test verilog/dv/sr_wb" The test for the LA is in verilog/dv/sr_la I think the random values are assigned to wProgData due to wbs_we_i getting high before we assign to the la/wb register. In your video you said 'wen' and 'wbs_cyc' get high/enabled once we write to the WB address. Could you tell me why 'wen' became high before you assign 0xFF to the reg_base_sr? Thank you
m
I'm going to guess that somehow the other writes are being optimised out. What do you think @Tim Edwards
t
@Edrisborne: What is this code intended to do?
Copy code
wire la_write;
assign la_write = ~la_oenb[BITS-1:0];
You are assigning a vector value to a single wire. But I think the main issue is here:
Copy code
always @(posedge clk) begin
        if (reset) begin
                sr_data <= 164'd0;
                ready <= 0;
        end else if(la_write || (valid && !ready && wen && (wb_addr == BASE_ADDR))) begin
                $display("writing");
                ready <=1;
                sr_data[WIDTH-1:1] <= sr_data[WIDTH-2:0];
                sr_data[0] <= Sin;
            end
    end
You are resetting
ready
only on reset. When there is a write, you set
ready
(which is
wb_ack_o
back to the wishbone master) high, but there is nothing in the code to set it low again, so your project is effectively blocking any further wishbone access. The correct code should be:
Copy code
always @(posedge clk) begin
        if (reset) begin
                sr_data <= 164'd0;
                ready <= 0;
        end else begin
            if (la_write || (valid && !ready && wen && (wb_addr == BASE_ADDR))) begin
                $display("writing");
                ready <=1;
                sr_data[WIDTH-1:1] <= sr_data[WIDTH-2:0];
                sr_data[0] <= Sin;
            end else begin
                ready <= 0;
            end
        end
    end
e
@Tim Edwards Thank you.