lekernel changed the topic of #milkymist to: Milkymist One, Migen, Milkymist SoC & Flickernoise :: Logs: http://en.qi-hardware.com/mmlogs :: EHSM Berlin Dec 28-30 http://ehsm.eu :: latest video http://www.youtube.com/playlist?list=PL181AAD8063FCC9DC
jimmythehorn has joined #milkymist
scrtss has quit []
rejon has joined #milkymist
azonenberg has quit [Ping timeout: 245 seconds]
azonenberg has joined #milkymist
rejon has quit [Ping timeout: 245 seconds]
lekernel has joined #milkymist
kilae has joined #milkymist
elldekaa has joined #milkymist
mumptai has joined #milkymist
azonenberg has quit [Ping timeout: 245 seconds]
jimmythehorn has quit [Read error: Connection reset by peer]
proppy has quit [Quit: Connection closed for inactivity]
azonenberg has joined #milkymist
<Fallenou> hum I wonder what happens when an exception happens (exception_x == TRUE) but stall_m or stall_x are TRUE, or q_x == FALSE
<Fallenou> Do we lose the exception ?
<Fallenou> We sould not lose the exception, in any case, 'cause exception origin could be an interrupt for example
<Fallenou> and interrupt can happen any time, without any concern on pipeline state (stalls, kills, etc)
<Fallenou> I don't understand why exception_x does not et propagated all the time to exception_m
<Fallenou> does not get*
<Fallenou> or maybe the exception_x signal *MUST* be kept high untill it gets propagated to exception_m ?
<Fallenou> that's what I am doing for now
<Fallenou> I keep i/d tlb miss flag asserted untill I see exception_m asserted
<Fallenou> but I find this strange
<wpwrak> losing an exception would be bad indeed. are interrupts edge-triggered ? because if they're level-triggered, then an interrupt that's not handled will simply come back in the next cycle
<Fallenou> in lm32_top.v interrupt pins are passed to lm32_cpu (pipeline) as a wire
<Fallenou> and then in lm32_interrupt.v there is a assign asserted = interrupt_pins & ie
<Fallenou> and then the exception_x gets assigned to (asserted & im) something like that
<Fallenou> it's all wire stuff, without any reg, so if the interrupt pin is de asserted before exception is triggered, there is no exception
<Fallenou> wpwrak: interrupts are level triggered
<Fallenou> but the level has to be kept for a few clock cycles sometimes
<Fallenou> you have to wait exception_m becomes `TRUE, to be *sure* that the exception will happen later on
<Fallenou> so you need to keep exception_x asserted, untill all condition for propagation from exception_x to exception_m are met
<Fallenou> like stall_m = false, stall_x=false, q_x = true
lekernel has quit [Read error: Operation timed out]
lekernel has joined #milkymist
lekernel_ has joined #milkymist
lekernel has quit [Ping timeout: 255 seconds]
<wpwrak> the general rule for level-triggered interrupts is that they have to be asserted until there is a reaction
<wpwrak> so that logic seems fine
<Fallenou> ok
jaho has joined #milkymist
jaho has quit [Quit: Salut a tous]
lekernel_ is now known as lekernel
<lekernel> interrupt inputs are edge triggered on the original LM32
<lekernel> a pulse sets the corresponding bit in IP at any time (regardless of the pipeline state)
<lekernel> and that bit stays set until IP is written (w1c)
<lekernel> the pipeline sees only a "level" type of signal that is asserted whenever at least one bit is asserted in IP
<lekernel> (in the LM32 used in -ng, I have removed this mechanism and made IP read-only, with its bit directly set by the now level-sensitive interrupt inputs. that should indeed be kept asserted by individual cores until there is a reaction from the CPU.)
<Fallenou> ok
<Fallenou> in milkymist master branch it's level sensitif, right ?
<Fallenou> you modified the original lm32
<lekernel> if you're using lm32 from milkymist-ng, it's level sensitive, yes
<lekernel> internally they're always level-sensitive anyway
<Fallenou> oh ok now i can see, asserted gets stored into ip
<Fallenou> ok got it thx
jimmythehorn has joined #milkymist
kilae has quit [Quit: ChatZilla 0.9.88.2 [Firefox 14.0.1/20120713134347]]
azonenberg has quit [Ping timeout: 245 seconds]
azonenberg has joined #milkymist
lekernel has quit [Quit: Konversation terminated!]
<Fallenou> itlb is really starting to work nicely on fpga
<Fallenou> it's really less buggy than it was a week ago now
<Fallenou> still something weird in ITLB miss handler
<Fallenou> let me pastebin it :)
<wpwrak> what was the big problem ?
<Fallenou> wpwrak: I was mostly putting delays in value propagations from reg to reg in clock cycles
<Fallenou> instead of doing it in "pipeline cycles"
<Fallenou> so in simulation it was "correct" because the two were correctly synchronized because I was able to see wire values etc
<Fallenou> but on fpga there is a lot of difference, because there is a real DDR SDRAM controler on the wishbone bus etc
<Fallenou> so I was doing it totally wrong :)
<Fallenou> now I look for stalls in the pipeline for instance
<Fallenou> and strangely, it works really better now !
<Fallenou> I can : enable itlb and jump to a function with it's virtual address
<Fallenou> I can run (with itlb enabled) a function calling puts() and printf(), with ITLB totally flushed
<Fallenou> which means it's going to generate a whole bunch of tlb miss (exceptions) , ITLB update and go back to code etc
<Fallenou> and it works
<Fallenou> "it works", but there is the bug I just posted in pastebin
<Fallenou> :)
<wpwrak> hmm. what does "delay" mean in this case ? i suppose isn't not something like "wait 100 ns here", is it ?
<Fallenou> no it's like cascading flip flops
<Fallenou> I want to use the value of regX, but two clock cycles later, I do always @(posedge clk) regX1 <= regX and always @(posedge clk) regX2 <= regX1; and I use regX2
<wpwrak> so you propagate between clock cycles ? i.e., from one "run" of an always block to its next "run" ?
<Fallenou> yes, I was doing things like that
<Fallenou> it kind of worked, but it was really stupid
<wpwrak> ah, perfect :) and i suppose these delays are constant, i.e., don't depend on, say, bus activity ?
<Fallenou> most of the time one clock cycle ~ 1 pipeline cycle but there are cases where you have stalls (upon branches, dcache refill, icache refill) and there you are screwed
<Fallenou> you cannot assume that pipeline will go forward at each clock cycle
<Fallenou> and I was assuming that
<wpwrak> ah, i see. so now you basically have a parallel pipeline
<Fallenou> but now I am turning crazy, because if I remove a rcsr it goes in an infinite exception loop :)
<wpwrak> and i can see how getting the delays wrong could cause very interesting bugs ;-))
<Fallenou> wpwrak: well not sure if I understand what you means, but now we can say that I am doing it correctly :)
<Fallenou> yes ^^
<Fallenou> wpwrak: my problem now is that somehow EA (exception address, where you branch upon eret) gets the value of itlb_miss_handler
<Fallenou> I don't get how, but it happens
<wpwrak> ;-))
<Fallenou> so when you eret, you branch to itlb_miss_handler, and then you eret etc etc
<Fallenou> and I just added a rcsr to read the value of PSW
<Fallenou> and it "fixed" the whole thing
<Fallenou> and btw PSW is correct, it's value is 0x10
<wpwrak> maybe you're coying the PC a little too late ?
<Fallenou> which means EITLBE = 1 and ITLBE = 0
<Fallenou> EITLBE = Exception ITLB enable | ITLBE = ITLB enabled
<Fallenou> upon exception ITLBE is copied to EITLBE and ITLBE is cleared
<Fallenou> so it seems correct
<Fallenou> too late or too early
<Fallenou> too early maybe
<wpwrak> sounds as if you're copying PC -> EA too late. i.e., after the exception has already been started.
<Fallenou> look at the logs, EA is correct two times
<Fallenou> for the first two ITLB misses
<Fallenou> and then it gets ***120 (which is itlb_miss_handler address)
<Fallenou> well you may be right, "too late"
<wpwrak> maybe it's concurrent ?
<Fallenou> wpwrak: do you see why just commenting/uncommenting the rcsr somehow fixes or not the whole thing ? :o
<Fallenou> I just don't get this
<Fallenou> the instruction is in the middle of the tlb handler
<wpwrak> maybe that's just coincidence. or maybe it affects cache timing or such.
<Fallenou> I think I'm going to commit/push ITLB to github
<Fallenou> now it's really less buggy
<wpwrak> if you have conflicting operations in the simulator, e.g., you assign to the same variable from two different places that could execute in parallel. what will the simulator do ? warn you ? pick always a given order ? pick an arbitrary but unspecified order ? or pick a randomize order ?
<Fallenou> you cannot assign the value variable from two places running in //
<Fallenou> it fails to "compile" in ISim and in Xst as well
<wpwrak> ah, i see
<wpwrak> pity. that takes the fun out of a lot of very interesting mistakes :)
<Fallenou> if you have a reg that you assign with "<=", you can assign it ONLY from one always block
<Fallenou> you can assign it in several if / else / switch case statements if you want
<wpwrak> how about "=" ?
<Fallenou> but you cannot have two different always blocks, assigning the same reg or wire
<Fallenou> it's the same
<Fallenou> to say it more efficiently : a signal can only be driven by one block
<Fallenou> 01:11 < wpwrak> pity. that takes the fun out of a lot of very interesting mistakes :) < there is already a lot of room for mistakes, trust me :p
<Fallenou> and I am doing a lot of them :D
<Fallenou> let's track how the pipeline writes to EA upon exception :'