OpenCores
Issue List
Problem #11
Closed Leineweber opened this issue over 13 years ago
Leineweber commented over 13 years ago

Hi, I use the mblite with Xilinx XPS 10.1 and the GNU C - compiler. The environment(PLB - bus) is adapted and can be substituted to the original microblaze.

But it doesn't run correctly.
asm(" lbui r3, r6, 0"); asm(" sbi r3, r4, 0"); // Error

asm(" lbui r3, r6, 0"); asm(" or r0, r0, r0"); asm(" sbi r3, r4, 0"); // ok

asm(" lbui r3, r6, 0"); asm(" addi r3, r3, 0"); asm(" sbi r3, r4, 0"); // ok

This are the defines for write back constant CFG_REG_FORCE_ZERO : boolean := true; constant CFG_REG_FWD_WRB : boolean := true; constant CFG_MEM_FWD_WRB : boolean := true;

Many thanks for qualified help Edgar

takar commented over 13 years ago

Thank you for the report! Do you know where the error originates exactly in the core? It might be that the value written to r3 is not properly forwarded or extended, or that it is not forwarded or extended at all.

Memory to memory forwarding does have complex timing issues. If you use xilinx bram the memory value written should be stable on the rising edge of the clock. However, at the same moment the value read from memory in the previous instruction has just became available. Inbetween these instructions, some asynchronous logic is necessary to forward, sign-extend and shift the data, which is not really pretty but unavoidable when using sync BRAM: both input and output should happen at the positive clock edge.

Could you please save me some time in reproducing this possible bug by sending me all relevant configuration and test files in order to reproduce the problem?

Leineweber commented over 13 years ago

Hi Tamar,

Thank you for the fast reply. Lets explain the setup.

I have a project with a Xylinx microblaze and I adapted it so I can switch between the the Microblaze and the Microblaze Lite. This way I can test if errors originate in the mbl or are on my behalf.

on a Xinlinx Spartan 3E the mb is connected to blockram using local memory bus, so I am writing and reading without the slow plb.

To get the MBL working I changed the clockspeed from 50mHz on the Xmb to 25 mHz on the MBL!

I noticed a strange behavior of the mbl when trying to run a small C test program. I isolated the problem to two assembler instructions.

When I do:

asm(" lbui r3, r6, 0"); asm(" sbi r3, r4, 0");

the result is faulty

if I play a little around, I get it working when I insert an Asm intruction that doesn't do any thing.

asm(" lbui r3, r6, 0"); asm(" or r0, r0, r0"); asm(" sbi r3, r4, 0"); // ok

asm(" lbui r3, r6, 0"); asm(" addi r3, r3, 0"); asm(" sbi r3, r4, 0"); // ok

You could say those instuctions don't change the registers so you simply delay one cycle. but even the next listing works ok

asm(" lbui r3, r6, 0"); asm(" addi r3, r3, 1"); asm(" sbi r3, r4, 0"); // ok

If on the adress of R6 there is an 31, The result on the adress of register R4 will be a 32

I tested the above in the simulator and every thing was ok, I simply cannot find any thing wrong with it. If you have any ideas or tests that I can do, I will gladly be of assistance.

Kind Regards

Edgar

Leineweber commented over 13 years ago

I found the cause of the faulty register contence. After the read data cycle the data is not stable for following cycles when the adress of the data changes (over different sources: bram<>external ram)

Inserting a edge-triggerd register in core.vhd solves the problem

process(rst_i, clk_i, ena_i, dmem_i)
begin
if rst_i = '1' then
        dat_reg <= (others => '0');
		
    elsif rising_edge(clk_i) then
        if ena_i = '1' then
            dat_reg <= dmem_i.dat_i;
    end if;
    end if;
end process;

mem_i.mem_result <= dat_reg; -- dmem_i.dat_i; exec_i.mem_result <= dat_reg; -- dmem_i.dat_i;

cheers,

Edgar

Leineweber commented over 13 years ago

Hi,

there appears to be another problem. "rsubk" doesn't work correctly.

explanation for the gnu compiler: in a function call the parameter 1 is in register 5, parameter 2 is in register 6.

lwi r24, r22, 44 // load variable 1 addk r5, r25, r0 // fkt() Param 1: buffer to display variable addk r6, r24, r0 // Param 2: variable brlid r15, -6220 // display content of r6 works correctly

lwi r23, r22, 36 // load variable 2 addk r5, r25, r0 // fkt() Param 1: buffer to display variable addk r6, r23, r0 // Param 2: variable
brlid r15, -6268 // display content of r6 works correctly

addk r5, r25, r0 // fkt() Param 1: buffer to display variable rsubk r6, r23, r24 // Param 2: variable brlid r15, -6312 // display content of r6 works correctly

// but if you make it directly rsubk doesn't work lwi r3, r22, 44 // load variable 1 lwi r6, r22, 36 // load variable 2 addk r5, r25, r0 // fkt() Param 1: buffer to display variable rsubk r6, r6, r3 // Param 2: variable brlid r15, -6364 // display content of r6 shows "0"

I have spent much time to incorporate and I want the part get up and running in our system.

Do you have any ideas to help

Kind Regards

Edgar

takar closed this almost 8 years ago

Assignee
No one
Labels
Bug