On Thu, Mar 29, 2012 at 8:41 AM, Olof Kindgren <[email protected]> wrote: > > > 2012/3/29 Ouabache Designworks <[email protected]> >> >> Ruben, >> >> The or1200_monitor.v really doesn't "handle" anything. It can detect when >> the cpu enters certain states and can pass that info back to the simulation >> but it doesn't affect the hardware. >> >> Passing information back to the sim is a lot trickier. You might be >> hitting a issue where your write is not aligned with a clock edge and it is >> overwritten at the next edge. Or you could >> be trying to write the registers during the same time that the software is >> trying to update them. >> >> It is very tempting and easy to access other parts of the simulation via >> software links it is also somewhat limiting. Yes your sim will work fine but >> when you get silicon back there is no >> way that you can run that sim on real silicon and get the same response. >> You are better off taking the time to add a gpio device and pass all your >> info through that. Yes it does take more >> time up front but you will be able to run that same test on real silicon >> and it will behave exactly as it did in the simulation. >> >> >> John Eaton >> >> >> >> >> >> >> On Wed, Mar 28, 2012 at 9:11 AM, R. Diez <[email protected]> >> wrote: >>> >>> Hi all: >>> >>> In order to run the or1ksim test suite against ORPSoCV2, I wanted to >>> support NOP codes like NOP_GET_TICKS and NOP_GET_PS in the Verilog test >>> bench. >>> >>> The current implementation in or1200_monitor.v already supports a few NOP >>> codes, look for "small hack to stop simulation (l.nop 1)" in that file. All >>> of the existing ones read some register value (usually R3) and do something >>> with them, like writing some trace string in the simulation log. However, >>> NOP_GET_TICKS and NOP_GET_PS need to write to some registers in order to >>> pass information back to the software that runs in the simulation. >>> >>> CPU registers are read with task get_gpr, which calls task >>> `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.get_gpr. I thought I could write to CPU >>> registers by calling the set_gpr counterpart. However, it turns out that the >>> values I write do not stay very long in the CPU registers. For example, if I >>> write to R3 while executing "l.nop NOP_GET_PS" and the next instruction is >>> an "l.nop NOP_EXIT", then the value survives, and the simulation exits with >>> the right value. But if the next instruction reads from R3, then the new >>> value is lost somewhere in the pipeline, it looks like R3 goes back to its >>> old value somehow. >>> >>> I traced set_gpr down to or1200_dpram.v, and the problem might be some >>> timing issue, as the new value for R3 is not written in a "normal" write >>> cycle inside the core, but directly to an internal Verilog array by some >>> foreign code outside that module. >>> >>> I always wondered why the special l.nop instructions are handled in >>> or1200_monitor.v , which feels somehow external to the CPU core. I thought >>> such instructions should be handled inside the core like any other regular >>> instructions. >>> >>> Can someone shed some light here? I don't know much about the CPU core >>> yet. Should I try to find some example code, like the implmentation for >>> l.add, and implement the special l.nops in the same way, so that the output >>> registers are written in the standard fashion? Where should I look for that >>> code? Or is there a quicker hack for simulation purposes so that writing to >>> registers works? >>> >>> Many thanks in advance, >>> Ruben >>> _______________________________________________ >>> OpenRISC mailing list >>> [email protected] >>> http://lists.openrisc.net/listinfo/openrisc >> >> >> >> _______________________________________________ >> OpenRISC mailing list >> [email protected] >> http://lists.openrisc.net/listinfo/openrisc >> > > Hi Ruben, > > For accessing the registers, I think you can use the GDB VPI interface. I > haven't used it myself, so I can't give you any pointers.
Accessing the registers via the emulated debug interface would certainly be a safer way of getting values into and out of the simulation, problem is they're not instantaneous (you need to do the transaction via the CPU's debug interface and can't reliably do this to the register file while the thing is running, which is the benefit of having the sneaky l.nop instructions to do it instantaneously.) > > I haven't looked very much at the or1ksim test suite, but here's a few ideas > regarding the NOP problems. > > There should be a tick timer in or1200 too. Could you use the to get the > number of ticks instead of using NOP_GET_TICKS. It would require some > rewriting of the test cases, and needs to be supported in or1ksim, but in > the long run it's probably a better solution. > > NOP_GET_PS is trickier, but is that really useful for anything other than > benchmarking the performance of the simulator itself? Maybe it should be > moved out of the testcases. I think the ticks l.nop should probably be removed and replaced with proper calls to the tick timer unit. They appear to be used in test-code-or1k/support/support.c in a function read_timer() which attempts to determine the "simulated" time by taking the simulated number of cycles, multiplying it by the simulated clock cycle period in picoseconds and then dividing by 1,000,000 to get the total time in miliseconds. Unfortunately there's no way of getting the CPU clock period value into the software via some hardware register officially, so I believe this l.nop for the picoseconds of the clock period is probably the best way to do this at the moment. Of course this could just be provided by the software (assume that all software tests are run at 100MHz - I don't think the ability to accurately measure time matters for these software tests) and have the read_timer() just get the tick timer cycles and assume a 10ns clock period. This would then remove some of the inconsistencies in the l.nop featuers between the different simulated models. Cheers Julius _______________________________________________ OpenRISC mailing list [email protected] http://lists.openrisc.net/listinfo/openrisc
