<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">Hellwig<div><br></div><div>Interesting questions. Most of them are left to the implementation...</div><div><div dir="ltr"><br></div><blockquote type="cite"><div dir="ltr"><span>1. What is the endianness of RISC5?</span><br></div></blockquote>Oberon code assuming a certain endianness is bad code. Why do you see the need to specify this? Of course, Oberon code can find out easily the endianness of the HW it‘s running on, but where does it matter? When I programmed the TCP stack, I could do certain shortcuts when I know the endianness. But whether net-order is the same as memory-order should not play a role: you should call in all curcumstances the translate procedure, even if it is empty.  In my point of view, endianness is a property of the environment/memory (RISC5Top.v) not of the RISC-5 CPU.</div><div><br><blockquote type="cite"><div dir="ltr"><span>2. Is the offset in memory instructions (format F2) sign-extended?</span><br></div></blockquote>As the Oberon machine only has 1 MB of memory, it makes no difference whether it is sign extended or not. However, the „official“ RISC-5 Verilog implementation has an address bus of 24bit (up to 16 MB). Yes: it sign extends „off“ as you can see here:</div><div><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">assign adr = stallL0 ? B[23:0] + {<b>{4{off[19]}}, off}</b> : {pcmux, 2'b00};</pre><blockquote type="cite"><div dir="ltr"><span>3. The SUB instruction "also sets the C flag". How is this to be</span><br><span>   interpreted? Example: compute 3-5. If you really subtract in</span><br><span>   binary, the carry will be set. If you add -5 in 2's complement</span><br><span>   representation, the carry will be cleared.</span><br></div></blockquote>If you subtract, RISC5.v sets the C bit according to this boolean expression </div><div><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">(~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa)</pre><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">Looking at your example a=3, b=5, c=-2 ==> C is set (1st rule)</pre><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">If you add, the C bit is set to the following boolean expression:</pre></div><div><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;"><pre style="word-wrap: break-word;"> (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa)</pre><pre style="word-wrap: break-word;">Looking at your example a=3, b=-5, c=-2 ==> C is set. (3rd rule)</pre><pre style="word-wrap: break-word;"><br></pre></pre><blockquote type="cite"><div dir="ltr"><span>4. What happens on (synchronous) exceptions?</span><br><span>   a) unaligned word access</span><br></div></blockquote><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">Not detected by the CPU. The environment (RISC5Top.v) just ignores the two lowest bits when accessing memory.</pre><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">assign SRadr = vidreq ? vidadr : adr[19:2];</pre><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">VAR m: INTEGER;</pre><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">SYSTEM.GET(0, m); SYSTEM.GET(1, m);</pre><pre style="-webkit-text-size-adjust: auto; word-wrap: break-word;">SYSTEM.GET(2, m); SYSTEM(3, m) return exactly the same m.</pre><blockquote type="cite"><div dir="ltr"><span>   b) unknown instruction</span></div></blockquote><div dir="ltr">The „op“ field in F0 and F1 are decoded completely. The u flag is only looked at if needed. There is no check whether u=0, when there is no special meaning for u=1.</div></div><div dir="ltr">So, as example: LSL behaves the same whether u=0 or u=1.</div><div><br><blockquote type="cite"><div dir="ltr"><span>   c) division by zero</span><br></div></blockquote>Integer (Divider.v): algorithm generates nonsense. So, the compiler generates check on 0 and generates a Trap.<br>Floating point(FPDivder.v): result is +-infinity depending on the sign of the numerator.</div><div><br><blockquote type="cite"><div dir="ltr"><span>   d) floating-point overflow</span><br></div></blockquote>Denormalized or 0 is generated.<br><blockquote type="cite"><div dir="ltr"><span>   e) floating-point underflow</span><br></div></blockquote>Result is NaN.</div><div><br><blockquote type="cite"><div dir="ltr"><span>5. What happens exactly on interrupt?</span></div></blockquote>When the irq signals becomes high, an interrupt is pending. It causes intAck to become high, if a) interrupts are enabled (intEnb), b) the processor is not currently executing another interrupt handler (~intMd), and c) the processor is not stalled. When intAck is high, the current PC is saved in the new SPC register, and pcmux becomes 1, i.e. the next instruction is read from address 4. At the same time, the condition bits are also saved (in SPC[21:18]), and the processor enters the interrupt mode.</div><div><br><blockquote type="cite"><div dir="ltr"><span>6. Are nested interrupts supported?</span><br></div></blockquote>No, see b) above</div><div><br><blockquote type="cite"><div dir="ltr"><span>7. Does STI delay the setting of intenb by one instruction?</span><br></div></blockquote>No. After execution of STI 1, intenb is set.<br><blockquote type="cite"><div dir="ltr"><span>   Does RTI automatically set intenb?</span><br></div></blockquote>No, RTI resets intMd, thus enabling interrupts again, if they were enabled before.</div><div>intMd can be seen as filter for intEnb.</div><div>Interrupts need one cycle to be detected.<span style="-webkit-text-size-adjust: auto;">   (irq1 <= irq;  // edge detector)</span></div><div><br><blockquote type="cite"><div dir="ltr"><span>   If both questions are answered negatively, then there is</span><br><span>   a race condition in the sequence (STI, RTI), with a nested</span><br><span>   interrupt as a possible result.</span><br></div></blockquote><br><blockquote type="cite"><div dir="ltr"><span>8. Can external devices other than the timer interrupt?</span><br></div></blockquote>Yes. „irq“ is an input signal to the CPU. The current implementation of RISC5Top.v sets irq equal to cnt==24999, so an interrupt every millisec. Other RISC5Top.v might do differently.</div><div><br><blockquote type="cite"><div dir="ltr"><span>9. All external devices are grossly underspecified.</span><br><span>(The list is not complete.)</span><br></div></blockquote><br><blockquote type="cite"><div dir="ltr"><span>Although I really want these questions to be answered, what</span><br><span>interests me most is: *how* do we find answers to them?</span><br><span>Some alternatives are:</span><br><span> - Anything that is not specified is intentionally left so.</span><br><span>   Implement at your free choice. This will severely hamper</span><br><span>   exchanging software, especially in binary form.</span><br><span> - Take NW's implementation and analyze the circuits (or</span><br><span>   just try it out). This promotes his implementation to</span><br><span>   a "reference design".</span><br><span> - Choose any one of the various simulators and declare it</span><br><span>   to be the "gold standard". Which one?</span><br><span> - Discuss each question here on the list and come to</span><br><span>   an agreement. A bit cumbersome, but manageable.</span><br><span>Other ideas?</span><br><span></span><br><span>Thanks,</span><br><span>Hellwig</span><br><span></span><br><span>[1] https://people.inf.ethz.ch/wirth/FPGA-relatedWork/RISC-Arch.pdf</span><br><span></span><br><span>--</span><br><span>Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems</span><br><span>https://lists.inf.ethz.ch/mailman/listinfo/oberon</span><br></div></blockquote></div></body></html>